Heikkonäköinen lukija ei erota mustaa tekstiä valkoisella sivulla oletuskontrastilla, joten hän pyytää tummaa tilaa. Naiivi vastaus on kääntää jokainen renderöidyn sivun pikseli. Se toimitetaan viikossa ja rikkoo seuraavana päivänä: skannatut valokuvat palaavat näyttäen filminegatiiveilta, lukijan keltaiset korostusmerkit muuttuvat lukukelvottomaksi siniseksi sivelyksi, ja joku kysyy miksi tuloste tuli täysin mustana. Ominaisuus on aidosti rakentamisen arvoinen ja aidosti helppo saada puolioikein, ja kuilu kahden lopputuloksen välillä on yksi idea: kukin värivalinta kuuluu tiettyyn pisteeseen renderöintiputkessa, ja invertointi on väärä työkalu sovellettuna väärässä vaiheessa. Koodi tässä käyttää PDFium Componentia, PDFium-pohjaista katselinta Delphille, C++Builderille ja Lazarukselle, jonka renderöintirajapinta paljastaa nuo vaiheet erikseen
Filterit ovat esitystila, eivät koskaan dokumenttitila
Yksi sääntö estää pahimman viraluokan täällä: lukutila muuttaa sitä miten bitmap tuotetaan tai jälkikäsitellään, eikä mitään muuta. PDF-tavut pysyvät koskemattomina, jokainen tila on peruutettavissa uudelleenrenderöimällä, ja "tallenna" ei koskaan kirjoita filteröityä ulkonäköä takaisin tiedostoon. Tämä kuulostaa ilmeiseltä kunnes lakitarkastaja tulostaa sopimuksen aktiivisen filterin alla ja arkistoi invertoidun version. Silloin kysymys "käyttääkö tulostus dokumentin omaa ulkonäköä vai ruudun" osoittautuu ansaitsevan eksplisiittisen vastauksen specissäsi, ei koodipolun onnettomuutta. Pidä filter-asetus katselimen tilassa, sovella se renderöintiaikana, ja tee jokainen vientipolu ilmoittaa minkä ulkonäön se käyttää
Sääntö maksaa itsensä takaisin kahdesti. Peruutettavuus tulee ilmaiseksi, koska tilojen vaihto renderöi uudelleen muuttumattomasta lähteestä: ei ole peruutuspinon ylläpitoa eikä mitään tapaa jolla peräkkäiset tilanvaihdot heikentäisivät sivua. Moni-ikkunaskenaariot pysyvät yhtenäisinä samasta syystä. Kahden saman dokumentin näkymää voi ajaa eri tiloja, koska kumpikin näkymä omistaa esitystilansa kun dokumenttiobjekti pysyy jaetuna
Renderöi ensin, muunna toiseksi
Tuettu malli on renderöinnin jälkeinen bitmap-käsittely: RenderPage tuottaa sivun rasterin, sitten muunnosläpikäynti säätää sitä. Komponentti toimittaa kolme muunnosta paikanvarsinaisina bitmap-operaatioina, InvertPdfBitmap, DuotonePdfBitmap ja GrayscalePdfBitmap, mikä tekee tilanvaihdosta puhdas kaksivaiheinen funktio:
function TViewerForm.RenderWithMode(W, H: Integer): TBitmap;
begin
Result := Pdf.RenderPage(0, 0, W, H, ro0, [reAnnotations]);
case FReadingMode of
rmInverted: InvertPdfBitmap(Result);
rmHighContrast: DuotonePdfBitmap(Result, clBlack, $0000C8FF); // tumma tausta, meripihkanvärinen teksti
rmGrayscale: GrayscalePdfBitmap(Result);
end;
// rmNormal putoaa läpi: asiakirja säilyttää omat värinsä
end;
Kaksi asiaa seuraa tästä suunnittelusta. Ensinnä, muunnoskustannus on suhteessa bitmapin kokoon, joten työ kuuluu sinne missä renderöintituloksesi on välimuistissa: filteröi välimuistitettu bitmap kerran, ei jokaisella maalauksella. Toiseksi, koska muunnos ajetaan valmiilla rasterilla, se osuu tekstiin, vektorigrafiikkaan, kuviin ja annotaatioulkonäköön samalla tavalla. Tuo yhtenäisyys on juuri se minkä pelkkä invertointi saa väärin valokuvien kohdalla. Se on syy miksi duotone-muunnos tekee paremman oletuksen tekstipitoisille dokumenteille, koska se kuvaa luminanssin valitulle tumma-vaalea värirammille sävyjen kieltämisen sijaan; invertointi pysyy saatavilla eksplisiittisenä valintana lukijoille jotka haluavat sen. Terävät glyfin reunat ovat erillinen vipu. reNoSmoothText-renderöintivalinta sammuttaa tekstin antialiasoinnin renderöintiaikana ja parittuu hyvin korkean kontrastin tilan kanssa suuressa zoomissa
Kaksi harmaasävyä jotka ovat eri mieltä
Renderöintivalintoihin kuuluu reGrayscale, joka näyttää oikotieltä jälkikäsittelyvaiheen ohi. Se ei ole sama operaatio:
// Moottoritaso: harmaasävy käytetty rasteroinnin aikana
GrayA := Pdf.RenderPage(0, 0, W, H, ro0, [reGrayscale]);
// Jälkikäsittely: renderöi värillisenä, muunna valmis bittikartta
GrayB := Pdf.RenderPage(0, 0, W, H);
GrayscalePdfBitmap(GrayB);
Enginitason valinta koskee kuvasisällön rasteritulostetta mutta ei yllä vektoritäyttöihin tai tekstiväreihin, joten sivu jossa on värit otsikot voi palata harmailla valokuvilla ja itsepäisesti sinisillä otsikoilla. GrayscalePdfBitmap valmiissa bitmapissa muuntaa kaiken, ehdottomasti. Renderöintivalinta ansaitsee silti paikkansa kun haluat kuvien olevan desaturoituja samalla kun pidät tekstin värin signaalina, mitä jotkut heikkonäköiset lukijat erityisesti suosivat. Mutta jos vaatimus lukee "harmaasävyinen sivu", jälkikäsittely on versio joka täyttää sen. Kumman polun valitsetkin, pidä molemmat RenderPage-ylikuormatyyliä mielessä. Funktiomuoto palauttaa bitmapin jonka kutsuja omistaa ja joka pitää vapauttaa, ja se merittaa heti kun filterit kertovat lensessä olevien renderöityjen bitmapien määrän
Taustat, valintamerkit ja PageColor-ansa
Ei jokainen mukavuussäätö ole muunnos. Valkoisen sivutaustan korvaaminen lämpimällä sävyllä on usein yksinään riittävä häikäistysherkillle lukijoille, ja sille on oma ominaisuus. Ominaisuus kantaa skooppiasääntöä joka nappaa ihmiset:
// Vaikuttaa vain näytöllä olevaan näkymään
PdfView.PageColor := $00D9EDF2; // lämmin paperisävy sivusisällön takana
// RenderPage-tuloste ei ota PageColoria huomioon; välitä väri nimenomaisesti
Bmp := Pdf.RenderPage(0, 0, W, H, ro0, [], $00D9EDF2);
PageColor muuttaa mitä TPdfView näyttää, mutta RenderPage:n kautta tuotetut bitmapit pitävät oletusvalkoisen ellei Color-parametri sano muuta. Oire on luotettava: ruutu näyttää sävytetyn sivun, käyttäjä vie tai tulostaa, ja tuloste palautuu valkoiseksi. Arkistoi se saman vientipolitiikkapäätöksen alle ensimmäisestä luvusta
Loput väriominaisuudet määrittelevät overlay-merkit: HighlightColor hakutreffeille, SelectionColor käyttäjän tekstivalinnalle, ReadingWordColor puhutun-sanan kursorille. Jokainen niistä on tarkistettava uudelleen jokaisen filterin alla jota tarjoat. Amberinen lukukursori joka toimii valkoisella katoaa invertoinnin jälkeen; vaaleansininen valinta katoaa korkean kontrastin taustaan. Ylläpidä per-tila-overlay-paletteja ennemmin kuin yhtä globaalia joukkoa, ja testaa yhdistelmät tahallaan. Filterit plus teksti-puheeksi on normaali konfiguraatio lukijoille joita tämä ominaisuus palvelee, ei reunatapaus. Overlay-koneisto itse on käsitelty saavutettavan lukijan artikkelissa
Numerot, verifiointi ja tulostuskysymys
WCAG 2.1 muuttaa tämän ominaisuuden joksikin mitä voit mitata. Onnistumiskriteeri 1.4.3 pyytää 4.5:1 kontrastisuhdetta leipätekstille, ja 1.4.6 nostaa sen 7:1:een tehostettua kontrastia varten. Tarkista korkean kontrastin tilasi nuo suhteet vasten kontrastianalysaattorilla ajettuna todellisessa renderöidyssä tulosteessa. Teksti kuvien päällä ja teksti lomakekentissä on siellä missä suhteet hiljaa epäonnistuvat silloinkin kun leipäteksti läpäisee
Tulostus ansaitsee oman päätöksensä, ja puolustettava oletus on dokumentin oma ulkonäkö, "tulosta näytetynä" tarjottuna eksplisiittisenä käyttäjävalintana. Tulostettu sivu on todiste useammissa vuoksissa kuin katselintekijät yleensä odottavat, ja invertitu sopimuksen tuloste on tukitapaus lakimaisella maustella. Vielä yksi paritus merittaa suorituskyvyn kannalta: filteröity renderöinti kaksinkertaistaa bitmaptyön jokaisella tilanvaihdolla, joten älä sovella muunnosta jokaisessa paint-viestissä. Välimuistita filteröity bitmap ja aja muunnos uudelleen vain kun sivu, zoom tai tila oikeasti muuttuu. Välimuististrategia joka tekee tästä halvan elää renderöintivälimuistin ja zoomin suorituskykyartikkelissa
Yksi asia ratkaista käyttöliittymässäsi ennemmin kuin koodissasi: mikä tila on oikea oletus. Ei ole yksittäistä vastausta, joten tarjoa joukko ja anna lukijan valita. Korkea kontrasti sopii useimmalle tekstipitoiselle lukemiselle, invertointi sopii lukijoille jotka erityisesti haluavat vaaleaa-tumman-varisella, harmaasävy leikkaa värikohinan, ja taustasävy käsittelee häikäistysherkkyyttä. Pysäytä valinta per käyttäjä, palauta se käynnistyksessä, ja pidä yhden näppäimen polku takaisin normaaliin, koska lukija joka laskeutuu tilaan jota hän ei voi lukea tarvitsee nopean ulospääsyn
Tässä käytetyt renderöintivalinnat, bitmap-muunnokset ja näkymän väriominaisuudet toimitetaan PDFium Component:n mukana Delphille, C++Builderille ja Lazarus/FPC:lle, täydellisen lähdekoodin kanssa jotta muunnostoteutukset voidaan auditoida tai laajentaa