Μία κουκκίδα εναλλάξ
Τετράγωνα γεμάτα ασπρόμαυρη διαγράμμιση μιας κουκκίδας, με πλευρά όσα pixel λέει κάθε πυκνότητα. Δύο πράγματα διαβάζονται πάνω τους: αν η οθόνη αποδίδει το μοτίβο ακέραιο, και ποια από τις πυκνότητες είναι η αληθινή, αν βάλεις χάρακα δίπλα.
τα μεγέθη δίνονται σε device pixels
Άδειο πεδίο σημαίνει «μη το ζωγραφίσεις»: χρησιμοποίησε όσα από τα τρία σε βολεύουν. Οι τιμές έρχονται από τη βαθμονόμησή σου στον χάρακα, και μπορείς να βάλεις όποιες θέλεις.
Το μοτίβο: μία σειρά κουκκίδων μαύρη, η επόμενη άσπρη. Είναι το πιο απαιτητικό σήμα που μπορεί να δεχτεί μια οθόνη, γιατί δεν υπάρχει περιθώριο να κρυφτεί κανένα σφάλμα. Αν η διαγράμμιση φαίνεται παντού ίδια και καθαρή, η εικόνα φτάνει στο τζάμι ακέραιη. Αν βλέπεις κάποιες γραμμές παχύτερες από άλλες, γκρίζες ζώνες ή φαρδιές μπάντες που κινούνται όταν κουνάς το κεφάλι σου, κάτι ξαναδειγματοληπτεί την εικόνα στη διαδρομή.
Ο χάρακας: ένα τετράγωνο με πλευρά N device pixel βγαίνει ακριβώς μία ίντσα (2,54 cm) αν και μόνο αν η πραγματική πυκνότητα είναι N ppi. Μέτρησε τα τετράγωνα: όποιο βγει 2,54 cm ονομάζει την αληθινή σου πυκνότητα, και τα υπόλοιπα δείχνουν πόσο έπεσε έξω η υπόθεση.
Προϋποθέσεις: ζουμ στο 100%, και μη βγάλεις screenshot για να το δείξεις αλλού. Ένα screenshot περνάει από δεύτερη δειγματοληψία και δείχνει σφάλματα που δεν είναι της οθόνης σου.
Τι να περιμένεις
Τετράγωνο 1 πλευρά — device pixel
Τετράγωνο 2 πλευρά — device pixel
Τετράγωνο 3 πλευρά — device pixel
Δώσε τουλάχιστον μία πυκνότητα για να ζωγραφιστεί ένα τετράγωνο.
Ανιχνεύει ξαναδειγματοληψία (resampling), δηλαδή ότι κάποιος πειράζει την εικόνα ανάμεσα στον φυλλομετρητή και το τζάμι. Δεν ανιχνεύει πυκνότητα: το σπασμένο μοτίβο σου λέει «κάτι συμβαίνει εδώ», δεν σου λέει πόσο πυκνό είναι το panel σου. Αυτό το απαντάει ο χάρακας, ή η βαθμονόμηση.
Και το αντίστροφο, που είναι εξίσου σημαντικό: καθαρή διαγράμμιση δεν σημαίνει «όλα καλά», σημαίνει «σε αυτή τη διαδρομή τίποτα δεν σμικρύνεται». Σε ζουμ 100% και χωρίς fractional scaling θα βγει τέλεια και δεν θα μάθεις τίποτα παραπάνω. Το κενό αποτέλεσμα είναι κι αυτό αποτέλεσμα.
Για δύο ανεξάρτητους λόγους. Πρώτον, το subpixel rendering: κάθε κουκκίδα μιας LCD είναι τρεις λωρίδες RGB η μία δίπλα στην άλλη, οριζόντια. Οι κάθετες γραμμές πέφτουν πάνω τους και μπορεί να βγουν με μοβ ή πράσινη απόχρωση, οι οριζόντιες όχι. Αν η μία σειρά έχει χρώμα και η άλλη είναι ουδέτερη, αυτό είναι πληροφορία για το πώς είναι φτιαγμένη η οθόνη.
Δεύτερον, η κλιμάκωση δεν είναι πάντα ίδια στους δύο άξονες, ούτε τα pixel πάντα τετράγωνα: η κλασική περίπτωση είναι ανάλυση 1280×1024 σε οθόνη 4:3. Αν σπάει μόνο η μία διεύθυνση, το μαθαίνεις μόνο αν έχεις και τις δύο μπροστά σου.
Δεν έχουν, και αυτό είναι σκόπιμο: η γραμμή είναι ένα device pixel και στα τρία, οπότε η διαγράμμιση βγαίνει πανομοιότυπη παντού. Αλλάζει μόνο το μέγεθος του τετραγώνου, γιατί άλλα τόσα device pixel ζητάει η κάθε πυκνότητα. Η σύγκριση εδώ γίνεται με τον χάρακα, όχι με το μάτι.
Το μοτίβο γράφεται με putImageData κατευθείαν σε device pixel: το backing store του canvas είναι N×N και το CSS μέγεθός του N/DPR. Έτσι παρακάμπτεται εντελώς το antialiasing και δεν μεσολαβεί καμία κλιμάκωση δική μας, ώστε ό,τι σπάσει να το έχει σπάσει το σύστημα και όχι η σελίδα.
Υπάρχει όμως μια παγίδα που δίνει ψευδώς θετικό: αν το ίδιο το canvas καθίσει σε μισό device pixel (πανεύκολο με κεντραρίσματα και fractional padding), η διαγράμμιση σπάει ακόμα και σε τέλεια οθόνη. Γι' αυτό η σελίδα μετράει τη θέση κάθε canvas μετά το layout και τη «μανταλώνει» σε ακέραιο device pixel με ένα διορθωτικό margin, και ξαναμετράει σε κάθε αλλαγή μεγέθους ή ζουμ.