/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġandroidx . ui . text Ċ Ċ import Ġandroidx . annotation . Restrict To Ċ import Ġandroidx . annotation . Restrict To . Scope . LIBRARY _ GROUP Ċ import Ġandroidx . annotation . Visible ForTesting Ċ import Ġandroidx . ui . core . Constraints Ċ import Ġandroidx . ui . core . Density Ċ import Ġandroidx . ui . core . Int Px Size Ċ import Ġandroidx . ui . core . Sp Ċ import Ġandroidx . ui . core . constr ain Ċ import Ġandroidx . ui . core . px Ċ import Ġandroidx . ui . core . round Ċ import Ġandroidx . ui . core . sp Ċ import Ġandroidx . ui . engine . geometry . Offset Ċ import Ġandroidx . ui . engine . geometry . Rect Ċ import Ġandroidx . ui . engine . geometry . Size Ċ import Ġandroidx . ui . text . style . Text Align Ċ import Ġandroidx . ui . text . style . Text Direction Ċ import Ġandroidx . ui . graphics . Color Ċ import Ġandroidx . ui . paint ing . Blend Mode Ċ import Ġandroidx . ui . paint ing . Canvas Ċ import Ġandroidx . ui . paint ing . Gradient Ċ import Ġandroidx . ui . paint ing . Paint Ċ import Ġandroidx . ui . paint ing . Shader Ċ import Ġandroidx . ui . text . font . Font Ċ import Ġandroidx . ui . text . style . Text Overflow Ċ import Ġkotlin . math . ceil Ċ Ċ private Ġval ĠDefault Text Align : ĠText Align Ġ= ĠText Align . Start Ċ private Ġval ĠDefault Text Direction : ĠText Direction Ġ= ĠText Direction . L tr Ċ /** ĠThe Ġdefault Ġfont Ġsize Ġif Ġnone Ġis Ġspecified . Ġ*/ Ċ private Ġval ĠDefault FontSize : ĠSp Ġ= Ġ 1 4 . sp Ċ Ċ /** Ċ Ġ* ĠUnfortunately , Ġusing Ġfull Ġprecision Ġfloating Ġpoint Ġhere Ġcauses Ġbad Ġlayouts Ġbecause Ġfloating Ċ Ġ* Ġpoint Ġmath Ġisn 't Ġassoci ative . ĠIf Ġwe Ġadd Ġand Ġsubtract Ġpadding , Ġfor Ġexample , Ġwe 'll Ġget Ċ Ġ* Ġdifferent Ġvalues Ġwhen Ġwe Ġestimate Ġsizes Ġand Ġwhen Ġwe Ġactually Ġcompute Ġlayout Ġbecause Ġthe Ċ Ġ* Ġoperations Ġwill Ġend Ġup Ġassociated Ġdifferently . ĠTo Ġwork Ġaround Ġthis Ġproblem Ġfor Ġnow , Ġwe Ġround Ċ Ġ* Ġfraction al Ġpixel Ġvalues Ġup Ġto Ġthe Ġnearest Ġwhole Ġpixel Ġvalue . ĠThe Ġright Ġlong - term Ġfix Ġis Ġto Ġdo Ċ Ġ* Ġlayout Ġusing Ġfixed Ġprecision Ġarithmetic . Ċ Ġ*/ Ċ internal Ġfun Ġapply Floating Point Hack ( layout Value : ĠFloat ): ĠFloat Ġ{ ĊĠĠĠ Ġreturn Ġceil ( layout Value ) Ċ } Ċ Ċ /** Ċ Ġ* ĠAn Ġobject Ġthat Ġpaint s Ġa Ġ[ Text Span ] Ġtree Ġinto Ġa Ġ[ Canvas ]. Ċ Ġ* Ċ Ġ* ĠTo Ġuse Ġa Ġ[ Text Painter ], Ġfollow Ġthese Ġsteps : Ċ Ġ* Ċ Ġ* Ġ 1 . ĠCreate Ġa Ġ[ Text Span ] Ġtree Ġand Ġpass Ġit Ġto Ġthe Ġ[ Text Painter ] Ġconstructor . Ċ Ġ* Ċ Ġ* Ġ 2 . ĠCall Ġ[ layout ] Ġto Ġprepare Ġthe Ġparagraph . Ċ Ġ* Ċ Ġ* Ġ 3 . ĠCall Ġ[ paint ] Ġas Ġoften Ġas Ġdesired Ġto Ġpaint Ġthe Ġparagraph . Ċ Ġ* Ċ Ġ* ĠIf Ġthe Ġwidth Ġof Ġthe Ġarea Ġinto Ġwhich Ġthe Ġtext Ġis Ġbeing Ġpaint ed Ġchanges , Ġreturn Ġto Ġstep Ġ 2 . ĠIf Ġthe Ċ Ġ* Ġ Ġtext Ġto Ġbe Ġpaint ed Ġchanges , Ġreturn Ġto Ġstep Ġ 1 . Ċ Ġ* Ċ Ġ* Ġ@ param Ġtext ĠThe Ġ( pot entially Ġstyled ) Ġtext Ġto Ġpaint . ĠAfter Ġthis Ġis Ġset , Ġyou Ġmust Ġcall Ġ[ layout ] Ċ Ġ* ĠĠ Ġbefore Ġthe Ġnext Ġcall Ġto Ġ[ paint ]. ĠThis Ġand Ġ[ text Direction ] Ġmust Ġbe Ġnon - null Ġbefore Ġyou Ġcall Ċ Ġ* ĠĠ Ġ[ layout ]. Ċ Ġ* Ċ Ġ* Ġ@ param Ġstyle ĠThe Ġtext Ġstyle Ġspecified Ġto Ġrender Ġthe Ġtext . ĠNotice Ġthat Ġyou Ġcan Ġalso Ġset Ġtext Ġstyle Ċ Ġ* Ġ Ġon Ġthe Ġgiven Ġ[ Annotated String ], Ġand Ġthe Ġstyle Ġset Ġon Ġ[ text ] Ġalways Ġhas Ġhigher Ġpriority Ġthan Ġthis Ċ Ġ* Ġ Ġsetting . ĠBut Ġif Ġonly Ġone Ġg ob al Ġtext Ġstyle Ġis Ġneeded , Ġpassing Ġit Ġto Ġ[ Text Painter ] Ġis Ġalways Ċ Ġ* Ġ Ġpreferred . Ċ Ġ* Ċ Ġ* Ġ@ param Ġparagraph Style ĠStyle Ġconfiguration Ġthat Ġapplies Ġonly Ġto Ġparagraphs Ġsuch Ġas Ġtext Ġalignment , Ċ Ġ* Ġor Ġtext Ġdirection . Ċ Ġ* Ċ Ġ* Ġ@ param Ġmax Lines ĠAn Ġoptional Ġmaximum Ġnumber Ġof Ġlines Ġfor Ġthe Ġtext Ġto Ġspan , Ġwrapping Ġif Ġnecessary . Ċ Ġ* ĠĠ ĠIf Ġthe Ġtext Ġexceeds Ġthe Ġgiven Ġnumber Ġof Ġlines , Ġit Ġis Ġtruncated Ġsuch Ġthat Ġsubsequent Ġlines Ġare Ċ Ġ* ĠĠ Ġdropped . Ċ Ġ* ĠĠ ĠAfter Ġthis Ġis Ġset , Ġyou Ġmust Ġcall Ġ[ layout ] Ġbefore Ġthe Ġnext Ġcall Ġto Ġ[ paint ]. Ċ Ġ* Ċ Ġ* Ġ@ param Ġsoft Wrap ĠWhether Ġthe Ġtext Ġshould Ġbreak Ġat Ġsoft Ġline Ġbreaks . Ċ Ġ* ĠĠ ĠIf Ġfalse , Ġthe Ġglyph s Ġin Ġthe Ġtext Ġwill Ġbe Ġposition ed Ġas Ġif Ġthere Ġwas Ġun limited Ġhorizontal Ġspace . Ċ Ġ* ĠĠ ĠIf Ġ[ soft Wrap ] Ġis Ġfalse , Ġ[ overflow ] Ġand Ġ[ textAlign ] Ġmay Ġhave Ġunexpected Ġeffects . Ċ Ġ* Ċ Ġ* Ġ@ param Ġoverflow ĠHow Ġvisual Ġoverflow Ġshould Ġbe Ġhandled . Ċ Ġ* ĠĠ ĠSpecific ally , Ġthe Ġellipsis Ġis Ġapplied Ġto Ġthe Ġlast Ġline Ġbefore Ġthe Ġline Ġtruncated Ġby Ġ[ max Lines ], Ċ Ġ* ĠĠ Ġif Ġ[ max Lines ] Ġis Ġnon - null Ġand Ġthat Ġline Ġoverflow s Ġthe Ġwidth Ġconstraint . Ċ Ġ* ĠĠ ĠAfter Ġthis Ġis Ġset , Ġyou Ġmust Ġcall Ġ[ layout ] Ġbefore Ġthe Ġnext Ġcall Ġto Ġ[ paint ]. Ċ Ġ* Ċ Ġ* Ġ@ param Ġlocale ĠThe Ġlocale Ġused Ġto Ġselect Ġregion - specific Ġglyph s . Ċ Ġ*/ Ċ class ĠText Painter ( ĊĠĠĠ Ġtext : ĠAnnot ated String ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġstyle : ĠTextStyle ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġparagraph Style : ĠParagraph Style ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġmax Lines : ĠInt ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġsoft Wrap : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġval Ġoverflow : ĠText Overflow Ġ= ĠText Overflow . Clip , ĊĠĠĠ Ġval Ġlocale : ĠLocale ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġdensity : ĠD ensity , ĊĠĠĠ Ġval Ġresource Loader : ĠFont . Resource Loader Ċ ) Ġ{ ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( max Lines Ġ== Ġnull Ġ|| Ġmax Lines Ġ> Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġvar Ġparagraph : ĠParagraph ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġvar Ġneeds Layout Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġvar Ġlayout Template : ĠParagraph ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġprivate Ġvar Ġoverflow Shader : ĠShader ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġvar Ġhas Visual Overflow Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġprivate Ġvar Ġlast Min Width : ĠFloat Ġ= Ġ 0 . 0 f ĊĠĠĠ Ġprivate Ġvar Ġlast Max Width : ĠFloat Ġ= Ġ 0 . 0 f ĊĊĠĠĠ Ġ@ Restrict To ( LIBRARY _ GROUP ) ĊĠĠĠ Ġvar Ġtext : ĠAnnot ated String ? Ġ= Ġtext ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field Ġ== Ġvalue ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparagraph Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġneeds Layout Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġval Ġtext Style : ĠTextStyle ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġstyle Ġ?: ĠTextStyle () ĊĊĠĠĠ Ġinternal Ġval ĠtextAlign : ĠText Align Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( paragraph Style ?. textAlign Ġ!= Ġnull ) Ġparagraph Style . textAlign Ġelse ĠDefault Text Align ĊĊĠĠĠ Ġinternal Ġval Ġtext Direction : ĠText Direction ? Ġ= ĊĠĠĠĠĠĠĠ Ġparagraph Style ?. text Direction Ġ?: ĠDefault Text Direction ĊĊĠĠĠ Ġprivate Ġval Ġis El lipsis Ġ= Ġ( overflow Ġ== ĠText Overflow . El lipsis ) ĊĊĠĠĠ Ġprivate Ġfun Ġcreate TextStyle (): ĠTextStyle Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtext Style . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠfontSize Ġ= Ġ( text Style . fontSize Ġ?: ĠDefault FontSize ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġcreate Paragraph Style (): ĠParagraph Style Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠParagraph Style ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠtextAlign Ġ= ĠtextAlign , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtext Direction Ġ= Ġtext Direction , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtext Indent Ġ= Ġparagraph Style ?. text Indent , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġline Height Ġ= Ġparagraph Style ?. line Height ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġheight Ġof Ġa Ġspace Ġin Ġ[ text ] Ġin Ġlogical Ġpixels . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠNot Ġevery Ġline Ġof Ġtext Ġin Ġ[ text ] Ġwill Ġhave Ġthis Ġheight , Ġbut Ġthis Ġheight Ġis Ġ" typ ical " Ġfor ĊĠĠĠĠ Ġ* Ġtext Ġin Ġ[ text ] Ġand Ġuseful Ġfor Ġs izing Ġother Ġobjects Ġrelative Ġa Ġtypical Ġline Ġof Ġtext . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠOb t aining Ġthis Ġvalue Ġdoes Ġnot Ġrequire Ġcalling Ġ[ layout ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġstyle Ġof Ġthe Ġ[ text ] Ġproperty Ġis Ġused Ġto Ġdetermine Ġthe Ġfont Ġsettings Ġthat Ġcontribute Ġto ĊĠĠĠĠ Ġ* Ġthe Ġ[ preferred Line Height ]. ĠIf Ġ[ text Style ] Ġis Ġnull , Ġthe Ġdefault Ġ[ TextStyle ] Ġvalues Ġare Ġused . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpreferred Line Height : ĠFloat ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( layout Template Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO ( Migration / qq d ): ĠThe Ġtext Direction Ġbelow Ġused Ġto Ġbe ĠRTL . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlayout Template Ġ= ĠParagraph ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġ" Ġ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstyle Ġ= Ġcreate TextStyle (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdirection Ġdoesn 't Ġmatter , Ġtext Ġis Ġjust Ġa Ġspace ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparagraph Style Ġ= Ġcreate Paragraph Style (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Styles Ġ= ĠlistOf (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmax Lines Ġ= Ġmax Lines , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġellipsis Ġ= Ġis El lipsis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdensity Ġ= Ġdensity , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresource Loader Ġ= Ġresource Loader ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlayout Template ?. layout ( Paragraph Constraints ( width Ġ= ĠFloat . POSITIVE _ INFINITY )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlayout Template !!. height ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġassert Needs Layout ( name : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġassert (! needs Layout ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Text Painter .$ name Ġshould Ġonly Ġbe Ġcalled Ġafter Ġlayout Ġhas Ġbeen Ġcalled ." ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġwidth Ġat Ġwhich Ġde creasing Ġthe Ġwidth Ġof Ġthe Ġtext Ġwould Ġprevent Ġit Ġfrom Ġpaint ing Ġitself ĊĠĠĠĠ Ġ* Ġcompletely Ġwithin Ġits Ġbounds . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠValid Ġonly Ġafter Ġ[ layout ] Ġhas Ġbeen Ġcalled . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġmin Intr insic Width : ĠFloat ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert Needs Layout (" min Intr insic Width ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġapply Floating Point Hack ( paragraph !!. min Intr insic Width ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġwidth Ġat Ġwhich Ġincreasing Ġthe Ġwidth Ġof Ġthe Ġtext Ġno Ġlonger Ġde creases Ġthe Ġheight . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠValid Ġonly Ġafter Ġ[ layout ] Ġhas Ġbeen Ġcalled . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġmax Intr insic Width : ĠFloat ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert Needs Layout (" max Intr insic Width ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġapply Floating Point Hack ( paragraph !!. max Intr insic Width ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġhorizontal Ġspace Ġrequired Ġto Ġpaint Ġthis Ġtext . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠValid Ġonly Ġafter Ġ[ layout ] Ġhas Ġbeen Ġcalled . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġwidth : ĠFloat ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert Needs Layout (" width ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġapply Floating Point Hack ( size . width ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġvertical Ġspace Ġrequired Ġto Ġpaint Ġthis Ġtext . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠValid Ġonly Ġafter Ġ[ layout ] Ġhas Ġbeen Ġcalled . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġheight : ĠFloat ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert Needs Layout (" height ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġapply Floating Point Hack ( size . height ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġamount Ġof Ġspace Ġrequired Ġto Ġpaint Ġthis Ġtext . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠValid Ġonly Ġafter Ġ[ layout ] Ġhas Ġbeen Ġcalled . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġsize : ĠSize Ġ= ĠSize ( 0 f , Ġ 0 f ) ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert Needs Layout (" size ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfield ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhether Ġany Ġtext Ġwas Ġtruncated Ġor Ġel lips ized . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġ[ max Lines ] Ġis Ġnot Ġnull , Ġthis Ġis Ġtrue Ġif Ġthere Ġwere Ġmore Ġlines Ġto Ġbe Ġdrawn Ġthan Ġthe Ġgiven ĊĠĠĠĠ Ġ* Ġ[ max Lines ], Ġand Ġthus Ġat Ġleast Ġone Ġline Ġwas Ġomitted Ġin Ġthe Ġoutput ; Ġotherwise Ġit Ġis Ġfalse . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġ[ max Lines ] Ġis Ġnull , Ġthis Ġis Ġtrue Ġif Ġ[ ellipsis ] Ġis Ġtrue Ġand Ġthere Ġwas Ġa Ġline Ġthat ĊĠĠĠĠ Ġ* Ġoverflow ed Ġthe Ġ` maxWidth ` Ġargument Ġpassed Ġto Ġ[ layout ]; Ġotherwise Ġit Ġis Ġfalse . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠValid Ġonly Ġafter Ġ[ layout ] Ġhas Ġbeen Ġcalled . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġdid Ex ceed Max Lines : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert Needs Layout (" did Ex ceed Max Lines ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġparagraph !!. did Ex ceed Max Lines ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠComputes Ġthe Ġvisual Ġposition Ġof Ġthe Ġglyph s Ġfor Ġpaint ing Ġthe Ġtext . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġtext Ġwill Ġlayout Ġwith Ġa Ġwidth Ġthat 's Ġas Ġclose Ġto Ġits Ġmax Ġintr insic Ġwidth Ġas Ġpossible ĊĠĠĠĠ Ġ* Ġwhile Ġstill Ġbeing Ġgreater Ġthan Ġor Ġequal Ġto Ġ` min Width ` Ġand Ġless Ġthan Ġor Ġequal Ġto Ġ` maxWidth `. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġ[ text ] Ġand Ġ[ text Direction ] Ġproperties Ġmust Ġbe Ġnon - null Ġbefore Ġthis Ġis Ġcalled . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġlayout Text ( min Width : ĠFloat Ġ= Ġ 0 . 0 f , ĠmaxWidth : ĠFloat Ġ= ĠFloat . POSITIVE _ INFINITY ) Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( text Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Text Painter . text Ġmust Ġbe Ġset Ġto Ġa Ġnon - null Ġvalue Ġbefore Ġusing Ġthe ĠText Painter ." ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġassert ( text Direction Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Text Painter . text Direction Ġmust Ġbe Ġset Ġto Ġa Ġnon - null Ġvalue Ġbefore Ġusing Ġthe " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ĠText Painter ." ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠTODO ( hao y uch ang ): Ġfix Ġthat Ġwhen Ġsoft Warp Ġis Ġfalse Ġand Ġoverflow Ġis ĠEl lipsis , Ġellipsis ĊĠĠĠĠĠĠĠ Ġ// Ġ Ġdoesn 't Ġwork . ĊĠĠĠĠĠĠĠ Ġval Ġwidth Mat ters Ġ= Ġsoft Wrap Ġ|| Ġoverflow Ġ== ĠText Overflow . El lipsis ĊĠĠĠĠĠĠĠ Ġval Ġfinal Max Width Ġ= Ġif Ġ( width Mat ters ) ĠmaxWidth Ġelse ĠFloat . POSITIVE _ INFINITY ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! needs Layout Ġ&& ĠminWidth Ġ== Ġlast Min Width Ġ&& Ġfinal Max Width Ġ== Ġlast Max Width ) Ġreturn ĊĠĠĠĠĠĠĠ Ġneeds Layout Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( paragraph Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparagraph Ġ= ĠParagraph ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġtext !!. text , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstyle Ġ= Ġcreate TextStyle (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparagraph Style Ġ= Ġcreate Paragraph Style (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Styles Ġ= Ġtext !!. text Styles , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmax Lines Ġ= Ġmax Lines , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġellipsis Ġ= Ġis El lipsis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdensity Ġ= Ġdensity , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresource Loader Ġ= Ġresource Loader ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlast Min Width Ġ= ĠminWidth ĊĠĠĠĠĠĠĠ Ġlast Max Width Ġ= Ġfinal Max Width ĊĠĠĠĠĠĠĠ Ġparagraph !!. layout ( Paragraph Constraints ( width Ġ= Ġfinal Max Width )) ĊĠĠĠĠĠĠĠ Ġif Ġ( min Width Ġ!= Ġfinal Max Width ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Width Ġ= Ġmax Intr insic Width . coerce In ( min Width , Ġfinal Max Width ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Width Ġ!= Ġparagraph !!. width ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparagraph !!. layout ( Paragraph Constraints ( width Ġ= Ġnew Width )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġlayout ( constraints : ĠConstraints ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlayout Text ( constraints . min Width . value . toFloat (), Ġconstraints . maxWidth . value . toFloat ()) ĊĊĠĠĠĠĠĠĠ Ġval Ġdid Overflow Height Ġ= Ġdid Ex ceed Max Lines ĊĠĠĠĠĠĠĠ Ġsize Ġ= Ġconstraints . constr ain ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠInt Px Size ( paragraph !!. width . px . round (), Ġparagraph !!. height . px . round ()) ĊĠĠĠĠĠĠĠ Ġ). let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSize ( it . width . value . toFloat (), Ġit . height . value . toFloat ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdid Overflow Width Ġ= Ġsize . width Ġ< Ġparagraph !!. width ĊĠĠĠĠĠĠĠ Ġ// ĠTODO ( ab arth ): ĠWe 're Ġonly Ġmeas uring Ġthe Ġsizes Ġof Ġthe Ġline Ġboxes Ġhere . ĠIf ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġglyph s Ġdraw Ġoutside Ġthe Ġline Ġboxes , Ġwe Ġmight Ġthink Ġthat Ġthere Ġisn 't ĊĠĠĠĠĠĠĠ Ġ// Ġvisual Ġoverflow Ġwhen Ġthere Ġactually Ġis Ġvisual Ġoverflow . ĠThis Ġcan Ġbecome ĊĠĠĠĠĠĠĠ Ġ// Ġa Ġproblem Ġif Ġwe Ġstart Ġhaving Ġhorizontal Ġoverflow Ġand Ġintroduce Ġa Ġclip ĊĠĠĠĠĠĠĠ Ġ// Ġthat Ġaffects Ġthe Ġactual Ġ( but Ġun detected ) Ġvertical Ġoverflow . ĊĠĠĠĠĠĠĠ Ġhas Visual Overflow Ġ= Ġdid Overflow Width Ġ|| Ġdid Overflow Height ĊĠĠĠĠĠĠĠ Ġoverflow Shader Ġ= Ġif Ġ( has Visual Overflow Ġ&& Ġoverflow Ġ== ĠText Overflow . Fade ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfade Size Painter Ġ= ĠText Painter ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= ĠAnnot ated String ( text Ġ= Ġ"\ u 2 0 2 6 ", Ġtext Styles Ġ= ĠlistOf ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstyle Ġ= Ġtext Style , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparagraph Style Ġ= Ġparagraph Style , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdensity Ġ= Ġdensity , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresource Loader Ġ= Ġresource Loader ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfade Size Painter . layout Text () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfade Width Ġ= Ġfade Size Painter . paragraph !!. width ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfade Height Ġ= Ġfade Size Painter . paragraph !!. height ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( did Overflow Width ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( fade Start , Ġfade End ) Ġ= Ġif Ġ( text Direction Ġ== ĠText Direction . R tl ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPair ( fade Width , Ġ 0 . 0 f ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPair ( size . width Ġ- Ġfade Width , Ġsize . width ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGradient . linear ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOffset ( fade Start , Ġ 0 . 0 f ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOffset ( fade End , Ġ 0 . 0 f ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Color ( 0 xFFFFFFFF . toInt ()), ĠColor ( 0 x 0 0 FFFFFF )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfade End Ġ= Ġsize . height ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfade Start Ġ= Ġfade End Ġ- Ġfade Height ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGradient . linear ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOffset ( 0 . 0 f , Ġfade Start ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOffset ( 0 . 0 f , Ġfade End ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Color ( 0 xFFFFFFFF . toInt ()), ĠColor ( 0 x 0 0 FFFFFF )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPaint s Ġthe Ġtext Ġonto Ġthe Ġgiven Ġcanvas Ġat Ġthe Ġgiven Ġoffset . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠValid Ġonly Ġafter Ġ[ layout ] Ġhas Ġbeen Ġcalled . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġyou Ġcannot Ġsee Ġthe Ġtext Ġbeing Ġpaint ed , Ġcheck Ġthat Ġyour Ġtext Ġcolor Ġdoes Ġnot Ġconflict Ġwith ĊĠĠĠĠ Ġ* Ġthe Ġbackground Ġon Ġwhich Ġyou Ġare Ġdrawing . ĠThe Ġdefault Ġtext Ġcolor Ġis Ġwhite Ġ( to Ġcontrast Ġwith ĊĠĠĠĠ Ġ* Ġthe Ġdefault Ġblack Ġbackground Ġcolor ), Ġso Ġif Ġyou Ġare Ġwriting Ġan Ġapplication Ġwith Ġa Ġwhite ĊĠĠĠĠ Ġ* Ġbackground , Ġthe Ġtext Ġwill Ġnot Ġbe Ġvisible Ġby Ġdefault . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠTo Ġset Ġthe Ġtext Ġstyle , Ġspecify Ġa Ġ[ TextStyle ] Ġwhen Ġcreating Ġthe Ġ[ Text Span ] Ġthat Ġyou Ġpass Ġto ĊĠĠĠĠ Ġ* Ġthe Ġ[ Text Painter ] Ġconstructor Ġor Ġto Ġthe Ġ[ text ] Ġproperty . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġpaint ( canvas : ĠCanvas , Ġoffset : ĠOffset ) Ġ{ ĊĠĠĠĠĠĠĠ Ġassert (! needs Layout ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Text Painter . paint Ġcalled Ġwhen Ġtext Ġgeometry Ġwas Ġnot Ġyet Ġcalculated .\ n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Please Ġcall Ġlayout () Ġbefore Ġpaint () Ġto Ġposition Ġthe Ġtext Ġbefore Ġpaint ing Ġit ." ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠIde ally Ġwe Ġcould Ġcompute Ġthe Ġmin / max Ġintr insic Ġwidth / height Ġwith Ġa ĊĠĠĠĠĠĠĠ Ġ// Ġnon - destruct ive Ġoperation . ĠHowever , Ġcurrently , Ġcomputing Ġthese Ġvalues ĊĠĠĠĠĠĠĠ Ġ// Ġwill Ġdestroy Ġstate Ġinside Ġthe Ġpainter . ĠIf Ġthat Ġhappens , Ġwe Ġneed Ġto ĊĠĠĠĠĠĠĠ Ġ// Ġget Ġback Ġthe Ġcorrect Ġstate Ġby Ġcalling Ġlayout Ġagain . ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠTODO ( ab arth ): ĠMake Ġcomputing Ġthe Ġmin / max Ġintr insic Ġwidth / height ĊĠĠĠĠĠĠĠ Ġ// Ġa Ġnon - destruct ive Ġoperation . ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġyou Ġremove Ġthis Ġcall , Ġmake Ġsure Ġthat Ġchanging Ġthe ĠtextAlign Ġstill ĊĠĠĠĠĠĠĠ Ġ// Ġworks Ġproperly . ĊĠĠĠĠĠĠĠ Ġ// ĠTODO ( Migration / qq d ): ĠNeed Ġto Ġfigure Ġout Ġwhere Ġthis Ġconstraints Ġcome Ġfrom Ġand Ġhow Ġto Ġmake ĊĠĠĠĠĠĠĠ Ġ// Ġit Ġnon - null . ĠFor Ġnow ĠCr ane ĠText Ġversion Ġdoes Ġnot Ġneed Ġto Ġlayout Ġtext Ġagain . ĠComment Ġit . ĊĠĠĠĠĠĠĠ Ġ// Ġlayout Text With Constraints ( constraints !! ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( has Visual Overflow ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbounds Ġ= Ġoffset . and ( size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( overflow Shader Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġlayer Ġlimits Ġwhat Ġthe Ġshader Ġbelow Ġbl ends Ġwith Ġto Ġbe Ġjust Ġthe Ġtext ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ( as Ġopposed Ġto Ġthe Ġtext Ġand Ġits Ġbackground ). ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . save Layer ( bounds , ĠPaint ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . save () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . clip Rect ( bounds ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġparagraph !!. paint ( canvas , Ġoffset . dx , Ġoffset . dy ) ĊĠĠĠĠĠĠĠ Ġif Ġ( has Visual Overflow ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( overflow Shader Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . translate ( offset . dx , Ġoffset . dy ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpaint Ġ= ĠPaint () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpaint . blend Mode Ġ= ĠBlend Mode . multiply ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpaint . shader Ġ= Ġoverflow Shader ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Rect ( Offset . zero . and ( size ), Ġpaint ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . restore () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDraw s Ġtext Ġbackground Ġof Ġthe Ġgiven Ġrange . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġthe Ġgiven Ġrange Ġis Ġempty , Ġdo Ġnothing . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġstart Ġinclusive Ġstart Ġoffset Ġof Ġthe Ġdrawing Ġrange . ĊĠĠĠĠ Ġ* Ġ@ param Ġend Ġexclusive Ġend Ġoffset Ġof Ġthe Ġdrawing Ġrange . ĊĠĠĠĠ Ġ* Ġ@ param Ġcolor Ġa Ġcolor Ġto Ġbe Ġused Ġfor Ġdrawing Ġbackground . ĊĠĠĠĠ Ġ* Ġ@ param Ġcanvas Ġthe Ġtarget Ġcanvas . ĊĠĠĠĠ Ġ* Ġ@ param Ġoffset Ġthe Ġdrawing Ġoffset . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġpaint Background ( start : ĠInt , Ġend : ĠInt , Ġcolor : ĠColor , Ġcanvas : ĠCanvas , Ġoffset : ĠOffset ) Ġ{ ĊĠĠĠĠĠĠĠ Ġassert (! needs Layout ) ĊĠĠĠĠĠĠĠ Ġif Ġ( start Ġ== Ġend ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġselection Path Ġ= Ġparagraph !!. getPath For Range ( start , Ġend ) ĊĠĠĠĠĠĠĠ Ġselection Path . shift ( offset ) ĊĠĠĠĠĠĠĠ Ġ// ĠTODO ( hao y uch ang ): Ġcheck Ġif Ġmove Ġthis Ġpaint Ġto Ġparameter Ġis Ġbetter ĊĠĠĠĠĠĠĠ Ġcanvas . draw Path ( selection Path , ĠPaint (). apply Ġ{ Ġthis . color Ġ= Ġcolor Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDraw s Ġthe Ġcursor Ġat Ġthe Ġgiven Ġoffset . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠTODO ( non a ): ĠMake Ġcursor Ġcustom izable . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġoffset Ġthe Ġcursor Ġoffset Ġin Ġthe Ġtext . ĊĠĠĠĠ Ġ* Ġ@ param Ġcanvas Ġthe Ġtarget Ġcanvas . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġpaint Cursor ( offset : ĠInt , Ġcanvas : ĠCanvas ) Ġ{ ĊĠĠĠĠĠĠĠ Ġassert (! needs Layout ) ĊĠĠĠĠĠĠĠ Ġval Ġcursor Rect Ġ= Ġparagraph !!. get Cursor Rect ( offset ) ĊĠĠĠĠĠĠĠ Ġcanvas . draw Rect ( cursor Rect , ĠPaint (). apply Ġ{ Ġthis . color Ġ= ĠColor . Black Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠReturns Ġthe Ġposition Ġwithin Ġthe Ġtext Ġfor Ġthe Ġgiven Ġpixel Ġoffset . Ġ*/ ĊĠĠĠ Ġfun Ġget Position For Offset ( offset : ĠOffset ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġassert (! needs Layout ) ĊĠĠĠĠĠĠĠ Ġreturn Ġparagraph !!. getPosition For Offset ( offset ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġbounding Ġbox Ġas ĠRect Ġof Ġthe Ġcharacter Ġfor Ġgiven Ġtext Ġposition . ĠRect Ġincludes Ġthe ĊĠĠĠĠ Ġ* Ġtop , Ġbottom , Ġleft Ġand Ġright Ġof Ġa Ġcharacter . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠValid Ġonly Ġafter Ġ[ layout ] Ġhas Ġbeen Ġcalled . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ hide ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Restrict To ( Restrict To . Scope . LIBRARY ) ĊĠĠĠ Ġfun Ġget BoundingBox ( offset : ĠInt ): ĠRect Ġ{ ĊĠĠĠĠĠĠĠ Ġassert (! needs Layout ) ĊĠĠĠĠĠĠĠ Ġreturn Ġparagraph !!. get BoundingBox ( offset ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġtext Ġrange Ġof Ġthe Ġword Ġat Ġthe Ġgiven Ġoffset . ĠChar acters Ġnot Ġpart Ġof Ġa Ġword , Ġsuch ĊĠĠĠĠ Ġ* Ġas Ġspaces , Ġsymbols , Ġand Ġpunctuation , Ġhave Ġword Ġbreaks Ġon Ġboth Ġsides . ĠIn Ġsuch Ġcases , Ġthis ĊĠĠĠĠ Ġ* Ġmethod Ġwill Ġreturn Ġa Ġtext Ġrange Ġthat Ġcontains Ġthe Ġgiven Ġtext Ġposition . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠWord Ġboundaries Ġare Ġdefined Ġmore Ġprecise ly Ġin ĠUnicode ĠStandard ĠAn nex Ġ# 2 9 ĊĠĠĠĠ Ġ* Ġ< http :// www . unicode . org / reports / tr 2 9 /# Word _ Bound aries >. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Word Boundary ( position : ĠInt ): ĠText Range Ġ{ ĊĠĠĠĠĠĠĠ Ġassert (! needs Layout ) ĊĠĠĠĠĠĠĠ Ġreturn Ġparagraph !!. get Word Boundary ( position ) ĊĠĠĠ Ġ} Ċ }