חישת קרניים 101

פול לואיס

מבוא

החלקת קצוות היא סוג של גיבור עלום בגרפיקה באינטרנט; זו הסיבה לכך שיש לנו טקסט ברור וצורות וקטור חלקות במסכים שלנו. כיום יש למעשה כמה גישות לאליטת קצוות בדפדפנים, שהן הבולטות ביותר כשמדובר בעיבוד טקסט. כשהאלגוריתם שמשמש נגד מתגים, עלול להיווצר תוצאות חזותיות לא צפויות. במאמר הזה נבחן את הגישות של החלקת קצוות ונראה איך משורטטים הפיקסלים.

כידוע, כל המסכים שלנו מורכבים מפיקסלים. מדובר ברשת ענקית של בלוקים, וכל אחד מהם מכיל רכיבים של אדום, ירוק וכחול (RGB). מרחוק אנחנו רואים תמונות, טקסט וסמלים, אבל מקרוב אפשר לראות את רשת רכיבי ה-RGB ואת המבנה של כל התוכן.

פיקסלים של מסך מקרוב. כל פיקסל מכיל רכיבים בצבע אדום, ירוק וכחול
איור 1 - פיקסלים של מסך מקרוב. בכל פיקסל יש רכיבים בצבע אדום, ירוק וכחול.

החלקת שינשון

אז מה קורה כשאנחנו משרטטים צורה וקטורית והיא עוברת דרך "חלק" מפיקסל? נניח שהצורה ששרטטנו היא שחורה והרקע לבן. האם כדאי לצבוע את הפיקסל הזה בכלל? באיזה צבע הוא צריך להיות? שחור, אפור, משהו אחר?

תהליך החלקת הקצוות קובע באיזה צבע עלינו להשתמש כשאנחנו ממלאים פיקסלים. הגרסה הפשוטה ביותר נקראת "יישור קצוות" בגווני אפור, והיא מתייחסת לשלושת הרכיבים של הפיקסלים באופן שווה. אז אם הפיקסל חצי מכוסה, ונניח טקסט שחור על גבי לבן לשנייה כדי לשמור על פשטות – אפשר להגדיר שכל רכיב יוגדר לחצי בהירות (אני יודע שזה בהחלט), אבל למעשה הוא מורכב יותר מזה: צריך להביא בחשבון את גאמה, כלומר סביר להניח שאף פעם לא תגדירו אותו לערך המדויק הזה. כמובן שזה קצת מסובך, אבל מאחר שזהו מבוא לנושא, לא ארחיב אותו כאן. מה שחשוב לדעת הוא שיישור קצוות בגווני אפור מטופל ברמת הפיקסל, ולמעשה אנחנו יכולים להשיג תוצאות טובות יותר.

איור 2 – עם קצוות מעוגלים לעומת קצוות קשים
איור 2 – קצוות אנכיים לעומת קצוות קשים

באיור 2 ניתן לראות שאותו משולש משורטט, אבל בצד שמאל מופעל בו קצוות קידומות, ובצד ימין הוא מושבת. כפי שאפשר לראות, כשהיישור החלקי מופעל, הפיקסלים מופיעים בגוונים של אפור כשהמשולש עובר רק דרך חלק מהפיקסל. עם זאת, כשהתכונה מושבתת, הפיקסל מלא בשחור מלא או בלבן מלא, והצורה נראית משוננת.

עיבוד טקסט

בכל פעם שדפדפן מעבד טקסט, שהוא למעשה צורה וקטורית, אנחנו נתקלים באותה בעיה: תווי הטקסט ימלאו רק באופן חלקי חלק מהפיקסלים, כך שנרצה שתהיה לנו אסטרטגיה למילוי הפיקסלים האלה. במצב אידיאלי, אנחנו רוצים שהטקסט יהיה עקיף, כי הוא יקל על הקריאה.

עם זאת, מסתבר שהגישה של גווני אפור לאליטת קצוות היא רק דרך אחת להתמודד עם זה. לעיתים קרובות נוקטים גישה קצת יותר סלקטיבית לגבי האופן שבו אנחנו מפעילים את רכיבי ה-RGB של הפיקסלים. התהליך נקרא יישור קצוות של תת-פיקסלים, ולאורך השנים במיוחד צוות ClearType ב-Microsoft השקיע זמן ומאמץ רב כדי להתקדם בתהליך. השימוש בו נפוץ יותר, וכל הדפדפנים הנפוצים משתמשים בו במידה רבה או נמוכה יותר.

ראשית, מכיוון שאנחנו יודעים שכל פיקסל מורכב למעשה מרכיבים נפרדים בצבעי אדום, ירוק וכחול, אנחנו מזהים כמה מכל אחד מהרכיבים האלה צריך להיות 'מופעל' עבור הפיקסל המדובר. לכן, אם פיקסל נמצא "לחצי מכוסה" מצד שמאל, יכול להיות שנעביר את הרכיב האדום לגמרי, את הרכיב הירוק עד לחצי השני, ונעביר את הצבע הכחול למצב כבוי. תהליך זה מתואר לעיתים קרובות כ"שלול הרזולוציה האופקית של המסך", ומסתמך על העובדה שכל פיקסל הוא למעשה שלושת הרכיבים הנפרדים זה לצד זה ולא יחידה בודדת.

איור 3 - ניתוח באמצעות גווני אפור לעומת תת-פיקסל
איור 3 – השוואה באמצעות גווני אפור לעומת תת-פיקסל

באיור 3 למעלה ניתן לראות שבצד ימין אנחנו מתייחסים לכל רכיב באופן שווה וכל אחד מהם מופעל או מושבת באופן שווה (גווני אפור). עם זאת, בצד שמאל אנחנו משתמשים בגישת תת-פיקסל (subpixel), וכך מאפשרים לכל רכיב (אדום, ירוק וכחול) באופן שונה, בהתאם למידת החפיפה שלו עם הצורה שמשרטטת.

עם זאת, הראייה האנושית לא תופסת בפועל משקל שווה של אור אדום, ירוק וכחול. אנחנו הרבה יותר רגישים לירוק מאשר אדום או כחול. פירוש הדבר הוא שאמנם יש יתרון מובהק לקישוט בגווני אפור, כפי שדריל רקס פינלי מציין, אבל הפעלה של כל רכיב בנפרד לא תוביל לשיפור הבהירות פי 3. עם זאת, יישור קצוות של תת-פיקסלים הוא בהחלט מועיל, ופירוש הדבר שאנחנו רואים את הטקסט בצורה ברורה יותר מאשר במקרה של שימוש ביישור קצוות בגווני אפור.

איור 4 - טקסט עם שכבת-על בפיקסלים משניים. רכיבים נפרדים של הפיקסלים מופעלים ליצירת האפקט הכולל
איור 4 - טקסט עם קצוות משנה בפיקסלים משניים. רכיבים נפרדים של הפיקסלים מופעלים ליצירת האפקט הכולל

ממשיכים לרוץ

איך כל זה משפיע על המפתחים? ובכן, מבחינת Chrome, לפחות יש שילוב של החלקת קצוות בגווני אפור ותת-פיקסלים לעיבוד טקסט, ואיזה מהם תלוי בכמה קריטריונים. עם זאת, תחילה עלינו להבין קצת את הנושא של שכבות, שכן זה הקריטריון העיקרי שנקבע. אם לא נתקלת בשכבות וכיצד Chrome משתמש בהן באופן פנימי, טום וילציוס כתב מבוא מעולה לנושא שכדאי לך לקרוא קודם.

בהנחה שאתם מכירים את השכבות, או שקראתם עליהן עכשיו, בואו נמשיך. אם איחוד חומרה מופעל בדף ויש תוכן טקסט בשכבה שאינה שכבת הבסיס, הוא יוצג כברירת מחדל באמצעות קצוות משוננים בגווני אפור. לעיתים קרובות מפתחים מבחינים בכך שאם הם מחילים פריצות לרכיבים כדי להעביר אותם לשכבות שלהם (שאינן ברמה הבסיסית) (למשל שימוש ב-TranslateZ), רואים שהטקסט מעובד בצורה שונה. לעיתים קרובות מפתחים מחילים טריגרים "שכבה חדשה" בזמן אמת באמצעות JavaScript או CSS, וכתוצאה מכך עיבוד הטקסט מתחלף מתת-פיקסל לגווני אפור. זה עלול לבלבל אם לא יודעים מה גרם לשינוי בעיבוד. עם זאת, אם הטקסט נמצא בשכבת השורש, צריך לעבד אותו באמצעות החלקת קצוות בתת-פיקסל, וכתוצאה מכך הוא יהיה הרבה יותר ברור לקריאה.

אבל כמו כל דבר באינטרנט, גם האינטרנט משתנה. קיצוץ של תת-פיקסלים מופעל ב-Chrome עבור טקסט בשכבות שאינן ברמה הבסיסית (root), בתנאי שהשכבה עומדת בשלושה קריטריונים. חשוב לציין שהקריטריונים האלה חלים היום, אבל סביר להניח שהם ישתנו ובמשך הזמן צפויים לראות עוד מקרים. היום הקריטריונים הם:

  1. לשכבה יש צבע רקע אטום לחלוטין. באופן בולט, אם משתמשים בערך border-radius או בערך background-clip שאינו ברירת מחדל, השכבה תתייחס לשכבה כשכבת-על לא אטומה, ועיבוד הטקסט הופך לקישוט בגווני אפור.
  2. השכבה יכולה להחיל רק טרנספורמציה של זהות או תרגום אינטגרלי. 'אינטגרל' הכוונה לערכים מעוגלים. אז לדוגמה, translate(20.2px, 30px) יפיק קצוות בגווני אפור כי רכיב ה-x, 20.2px, לא שלם. המשמעות של טרנספורמציה של זהות היא שלא מחילים שינויים נוספים, כמו סיבוב, תרגום או התאמה לעומס (scaling) מעבר לברירת המחדל שלה.
  3. לשכבה יש שקיפות של 1.0. כל שינוי באטימות ישנה את ההטיות לפנים מ'תת-פיקסל' לגווני אפור.
איור 5 - לפני ואחרי: גווני אפור לעומת תת-פיקסל. שימו לב
    לשוליים של הטקסט שמשמאל
איור 5 - לפני ואחרי: גווני אפור לעומת תת-פיקסל. שימו לב לשוליים של הטקסט שמשמאל

עוד דבר שחשוב לדעת הוא שהחלת אנימציית CSS עשויה לגרום ליצירת שכבה חדשה, ואילו השימוש ב-requestAnimationFrame לא גורם לכך. אצל מפתחים מסוימים, ההבדלים בעיבוד הטקסט, שמרמזים על כך, מנעו את השימוש באנימציות CSS. לכן, אם השתמשתם ב-JavaScript כדי להנפיש אלמנטים מסוימים עקב הבדלים בעיבוד הטקסט, בדקו אם העדכון הזה פותר את הבעיה.

וכאן אנחנו מטפלים ב-Chrome. כשמדובר בדפדפנים אחרים, Opera ככל שהיא עוברת ל-Chromium, היא צריכה להתאים היטב להתנהגות של Chrome. נראה ש-Internet Explorer משתמש בהטיית קצוות תת-פיקסלים כמעט בכל הטקסט (אם הפעלת את ClearType, כמובן!), למרות שלכאורה לא במצב Metro של Windows 8. Safari, לאור הקרבה של WebKit ל-Blink, מתנהג באופן דומה מאוד ל-Chrome, רק אם ללא השיפורים החדשים האלה שמאפשרים קצוות תת-פיקסלים רבים יותר. מאחר ש-Firefox פועל ברובו באותו אופן כמו Internet Explorer, הוא משתמש בהטיית קצוות בתת-פיקסלים כמעט בכל הטקסט. כמובן שזוהי רשימה חלקית בלבד, וסביר להניח שיהיו מקרים בכל הדפדפנים שבהם נעשה שימוש ביישור קצוות בגווני אפור במקום בתת-פיקסל, אבל טוב לדעת שיישור קצוות של תת-פיקסלים נמצא בשימוש נפוץ בקבוצה הראשית של הדפדפנים.

סיכום

אז עכשיו אתם יודעים קצת על אופן הפעולה של קצוות משוננים, ולמה עשויים להיות הבדלים ברינדור הטקסט באתרים ובאפליקציות שלכם כיום, במיוחד במכשירים עם DPI נמוך יותר. אם אתם מעוניינים לעקוב אחר ההטמעה של Chrome ביחס לעיבוד טקסט, עליכם לסמן את הבאגים הבאים בכוכב:

מקורות מידע והפניות