DTPText.Mod 119 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305
  1. MODULE DTPText; (** AUTHOR "PL"; PURPOSE "Text Plugin for DTPEditor"; *)
  2. IMPORT
  3. KernelLog, Modules, Inputs, Streams, Files, XML, WMGrids,
  4. WMStandardComponents, WMGraphics, WMGraphicUtilities, WMDropTarget, WMStringGrids,
  5. WMComponents, WMRectangles, WMDialogs, WMProperties, WMRasterScale,
  6. WMEditors, Strings, TextUtilities, Texts, XMLObjects, UTF8Strings,
  7. WMWindowManager, Raster, DTPEditor, DTPData, DTPUtilities;
  8. CONST
  9. pluginVersion = 1.00;
  10. pluginName = "Text";
  11. pluginDesc = "Text Plugin for DTPEditor";
  12. point = 0.3527777778; (* 1/72 inch *)
  13. TraceRenderOptimize = 0;
  14. TraceLayout = 1;
  15. TraceBaseLine = 2;
  16. TraceInvalidate = 3;
  17. Trace = { };
  18. Wrap* = 0; WrapWord* = 1;
  19. AlignLeft = 0; AlignCenter = 1; AlignRight = 2; AlignJustified = 3;
  20. HLOver* = 0; HLUnder* = 1; HLWave* = 2;
  21. DragDist = 5;
  22. CR = 0DX; LF = 0AX;
  23. VAR
  24. TYPE
  25. Char32 = Texts.Char32;
  26. String = Strings.String;
  27. Image* = OBJECT
  28. VAR
  29. image* : WMGraphics.Image;
  30. file* : String;
  31. END Image;
  32. TabStops* = OBJECT
  33. VAR tabDist : LONGINT;
  34. (* return the next TabStop from the x position *)
  35. PROCEDURE GetNextTabStop*(x : LONGINT) : LONGINT;
  36. BEGIN
  37. RETURN ((x DIV tabDist) + 1) * tabDist
  38. END GetNextTabStop;
  39. END TabStops;
  40. LineInfo = RECORD
  41. height, ascent, spaceSize : REAL;
  42. width : LONGINT;
  43. pos : LONGINT; (* the position in the text, where this line starts *)
  44. align : LONGINT;
  45. flags : SET;
  46. tabStops : TabStops;
  47. firstInParagraph, lastInParagraph, lastInText: BOOLEAN;
  48. eotSize: LONGINT;
  49. leading, firstIndent, leftIndent, rightIndent, spaceBefore, spaceAfter: REAL;
  50. END;
  51. LineInfoArray = POINTER TO ARRAY OF LineInfo;
  52. Layout = OBJECT
  53. VAR
  54. nofLines : LONGINT;
  55. lines : LineInfoArray;
  56. text : Texts.Text;
  57. paperWidth: LONGINT;
  58. textWidth : LONGINT; (* maximal width of the text <= textWidth *)
  59. textHeight : LONGINT;
  60. realHeight, realWidth: REAL;
  61. layoutLineProc : PROCEDURE {DELEGATE} (VAR pos : LONGINT; VAR lineInfo : LineInfo; lineNr, wrapWidth, stopPos, stopXPos : LONGINT; fcur: BOOLEAN);
  62. PROCEDURE &New*;
  63. BEGIN
  64. NEW(lines, 4)
  65. END New;
  66. (** Replace the text *)
  67. PROCEDURE SetText*(t : Texts.Text);
  68. BEGIN
  69. text := t
  70. END SetText;
  71. PROCEDURE GrowLines;
  72. VAR i : LONGINT; newLines : LineInfoArray;
  73. BEGIN
  74. NEW(newLines, LEN(lines) * 2);
  75. FOR i := 0 TO LEN(lines) - 1 DO newLines[i] := lines[i] END;
  76. lines := newLines
  77. END GrowLines;
  78. (** find the linenumber by the position *)
  79. PROCEDURE FindLineNrByPos(pos : LONGINT) : LONGINT;
  80. VAR a, b, m: LONGINT;
  81. BEGIN
  82. a := 0; b := nofLines - 1;
  83. WHILE (a < b) DO m := (a + b) DIV 2;
  84. IF lines[m].pos <= pos THEN a := m + 1
  85. ELSE b := m
  86. END
  87. END;
  88. (* last line hack *)
  89. IF lines[a].pos <= pos THEN INC(a) END;
  90. (* i := 0; WHILE (i < nofLines) & (lines[i].pos <= pos) DO INC(i) END;
  91. IF a - 1 # i - 1 THEN
  92. KernelLog.String("OffByOne"); KernelLog.String("a - 1 = "); KernelLog.Int(a - 1, 0); KernelLog.String(" i - 1 = "); KernelLog.Int(i - 1, 0); KernelLog.Ln;
  93. END; *)
  94. RETURN a - 1
  95. END FindLineNrByPos;
  96. PROCEDURE GetLineStartPos(lineNr : LONGINT) : LONGINT;
  97. BEGIN
  98. IF (lineNr >= 0) & (lineNr < nofLines) THEN RETURN lines[lineNr].pos ELSE RETURN 0 END
  99. END GetLineStartPos;
  100. (** return the length in characters of this line *)
  101. PROCEDURE GetLineLength(lineNr : LONGINT) : LONGINT;
  102. BEGIN
  103. IF (lineNr >= 0) & (lineNr < nofLines - 1) THEN RETURN lines[lineNr + 1].pos - lines[lineNr].pos
  104. ELSE
  105. IF (lineNr >= 0) & (lineNr < nofLines) THEN RETURN text.GetLength() - lines[lineNr].pos + 1
  106. ELSE RETURN 0
  107. END
  108. END
  109. END GetLineLength;
  110. PROCEDURE GetNofLines() : LONGINT;
  111. BEGIN
  112. RETURN nofLines
  113. END GetNofLines;
  114. PROCEDURE LayoutLine(VAR pos : LONGINT; VAR lineInfo : LineInfo; currentLine: LONGINT);
  115. BEGIN
  116. IF layoutLineProc # NIL THEN layoutLineProc(pos, lineInfo, currentLine, paperWidth, -1, -1, FALSE) END
  117. END LayoutLine;
  118. (* generate a new layout from scratch *)
  119. PROCEDURE FullLayout(startpos, startline: LONGINT);
  120. VAR i, pos, oldpos : LONGINT;
  121. BEGIN
  122. IF text = NIL THEN RETURN END;
  123. textWidth := 0;
  124. ASSERT(lines#NIL);
  125. text.AcquireRead;
  126. IF TraceLayout IN Trace THEN KernelLog.String("FullLayout"); KernelLog.Ln END;
  127. i := 0;
  128. pos := startpos; nofLines := startline;
  129. textHeight := 0; realHeight := 0;
  130. WHILE pos < text.GetLength() DO
  131. oldpos := pos;
  132. (* KernelLog.String("LineNR: "); KernelLog.Int(nofLines, 0); KernelLog.Ln; *)
  133. LayoutLine(pos, lines[nofLines], nofLines);
  134. realHeight := realHeight + lines[nofLines].height; textHeight := ENTIER(realHeight);
  135. textWidth := ENTIER(DTPUtilities.Max(textWidth, lines[nofLines].width));
  136. ASSERT(pos > oldpos);
  137. IF TraceLayout IN Trace THEN KernelLog.String("Line from : "); KernelLog.Int(lines[nofLines].pos, 5); KernelLog.Ln END;
  138. (* lines[nofLines].align := AlignLeft; *)
  139. INC(nofLines); IF nofLines >= LEN(lines) THEN GrowLines END
  140. END;
  141. IF TraceLayout IN Trace THEN KernelLog.String("FullLayout found "); KernelLog.Int(nofLines, 4); KernelLog.String(" lines"); KernelLog.Ln END;
  142. text.ReleaseRead
  143. END FullLayout;
  144. (** Fix the layouting of the text starting at pos where delta characters have been inserted (delta negativ if deleted) *)
  145. PROCEDURE FixLayoutFrom(pos, delta : LONGINT; VAR first, last : LONGINT; VAR linesChanged : BOOLEAN; firstpos, firstline: LONGINT);
  146. VAR l, dl : LONGINT;
  147. oldh, tempHeight: REAL;
  148. BEGIN
  149. ASSERT(text#NIL);
  150. text.AcquireRead;
  151. linesChanged := FALSE;
  152. l := FindLineNrByPos(pos);
  153. (* KernelLog.String("Linenr: "); KernelLog.Int(l, 0); KernelLog.Ln; *)
  154. (* KernelLog.String("RealHeight: "); DTPUtilities.OutReal(realHeight, 4); KernelLog.Ln; *)
  155. IF (l < 0) THEN FullLayout(firstpos, firstline); first := 0; last := nofLines; text.ReleaseRead; RETURN END;
  156. pos := lines[l].pos;
  157. oldh := lines[l].height;
  158. LayoutLine(pos, lines[l], l);
  159. IF oldh # lines[l].height THEN linesChanged := TRUE END;
  160. first := l;
  161. INC(l); dl := 0;
  162. IF (delta < 0) THEN
  163. IF (l >= nofLines) OR (lines[l].pos + delta = pos) THEN
  164. last := l;
  165. WHILE (l < nofLines) DO lines[l].pos := lines[l].pos + delta; INC(l) END
  166. ELSE
  167. linesChanged := TRUE;
  168. WHILE (pos < text.GetLength()) DO
  169. (* KernelLog.String("Line: "); KernelLog.Int(l, 0);
  170. IF (l>=LEN(lines)) THEN KernelLog.String("height: NIL") ELSE KernelLog.String("height: "); DTPUtilities.OutReal(lines[l].height,4); END;
  171. KernelLog.Ln;
  172. *) IF (l >= LEN(lines)) THEN tempHeight := 0.0 ELSE tempHeight := lines[l].height; END;
  173. realHeight := realHeight - tempHeight;
  174. LayoutLine(pos, lines[l], l);
  175. textWidth := ENTIER(DTPUtilities.Max(textWidth, lines[l].width));
  176. realHeight := realHeight + lines[nofLines].height;
  177. INC(dl);
  178. IF TraceLayout IN Trace THEN KernelLog.String("Line from : "); KernelLog.Int(lines[nofLines].pos, 5); KernelLog.Ln END;
  179. INC(l); IF l >= LEN(lines) THEN GrowLines END;
  180. END;
  181. textHeight := ENTIER(realHeight);
  182. nofLines := l ;
  183. last := nofLines - 1
  184. END
  185. ELSE
  186. WHILE (pos < text.GetLength()) & (lines[l].pos + delta # pos) DO
  187. linesChanged := TRUE;
  188. realHeight := realHeight - lines[l].height;
  189. LayoutLine(pos, lines[l], l);
  190. textWidth := ENTIER(DTPUtilities.Max(textWidth, lines[l].width));
  191. realHeight := realHeight + lines[nofLines].height;
  192. INC(dl);
  193. IF TraceLayout IN Trace THEN KernelLog.String("Line from : "); KernelLog.Int(lines[nofLines].pos, 5); KernelLog.Ln END;
  194. INC(l); IF l >= LEN(lines) THEN GrowLines END;
  195. END;
  196. textHeight := ENTIER(realHeight);
  197. last := l;
  198. IF TraceLayout IN Trace THEN
  199. KernelLog.String("Delta Lines : "); KernelLog.Int(dl, 4); KernelLog.Ln;
  200. KernelLog.String("Lines to redraw : "); KernelLog.Int(first, 5); KernelLog.String(" to "); KernelLog.Int(last, 5); KernelLog.Ln
  201. END;
  202. (* fix up the positions *)
  203. IF l < nofLines THEN WHILE (l < nofLines) DO lines[l].pos := lines[l].pos + delta; INC(l) END
  204. ELSE nofLines := l
  205. END
  206. END;
  207. text.ReleaseRead
  208. END FixLayoutFrom;
  209. END Layout;
  210. Highlight* = OBJECT
  211. VAR
  212. kind : LONGINT;
  213. from*, to* : Texts.TextPosition;
  214. a*, b* : LONGINT; (* only valid after sort, while holding the lock *)
  215. active* : BOOLEAN; (* only valid after sort, while holding the lock *)
  216. oldFrom, oldTo : LONGINT;
  217. color : WMGraphics.Color;
  218. text : Texts.UnicodeText;
  219. (* onChanged : WMMessages.CompCommand; *)
  220. onChanged* : PROCEDURE {DELEGATE} (sender, data: ANY);
  221. owner : TextObject;
  222. PROCEDURE &New*;
  223. BEGIN
  224. color := 0FF80H
  225. END New;
  226. PROCEDURE SetOwner(owner : TextObject);
  227. BEGIN
  228. SELF.owner := owner;
  229. onChanged := owner.HighlightChanged;
  230. END SetOwner;
  231. PROCEDURE SetKind*(kind : LONGINT);
  232. BEGIN
  233. IF SELF.kind # kind THEN
  234. SELF.kind := kind;
  235. onChanged(SELF, NIL)
  236. END
  237. END SetKind;
  238. PROCEDURE SetColor*(color : WMGraphics.Color);
  239. BEGIN
  240. IF SELF.color # color THEN
  241. SELF.color := color;
  242. onChanged(SELF, NIL)
  243. END
  244. END SetColor;
  245. PROCEDURE SetFrom*(from : LONGINT);
  246. BEGIN
  247. IF text = NIL THEN RETURN END; (* if no text is set, the position within is undef *)
  248. text.AcquireRead;
  249. oldFrom := SELF.from.GetPosition();
  250. IF oldFrom # from THEN
  251. SELF.from.SetPosition(from);
  252. onChanged(SELF, NIL)
  253. END;
  254. text.ReleaseRead
  255. END SetFrom;
  256. PROCEDURE SetTo*(to : LONGINT);
  257. BEGIN
  258. IF text = NIL THEN RETURN END; (* if no text is set, the position within is undef *)
  259. text.AcquireRead;
  260. oldTo := SELF.to.GetPosition();
  261. IF oldTo # to THEN
  262. SELF.to.SetPosition(to);
  263. onChanged(SELF, NIL)
  264. END;
  265. text.ReleaseRead
  266. END SetTo;
  267. PROCEDURE SetFromTo*(from, to : LONGINT);
  268. BEGIN
  269. IF text = NIL THEN RETURN END; (* if no text is set, the position within is undef *)
  270. text.AcquireRead;
  271. oldTo := SELF.to.GetPosition();
  272. oldFrom := SELF.from.GetPosition();
  273. IF (oldTo # to) OR (oldFrom # from) THEN
  274. IF ((oldTo = oldFrom) & (to = from)) THEN
  275. SELF.to.SetPosition(to);
  276. SELF.from.SetPosition(from)
  277. ELSE
  278. SELF.to.SetPosition(to);
  279. SELF.from.SetPosition(from);
  280. onChanged(SELF, NIL)
  281. END
  282. END;
  283. text.ReleaseRead
  284. END SetFromTo;
  285. PROCEDURE Sort*;
  286. VAR t : LONGINT;
  287. BEGIN
  288. a := from.GetPosition();
  289. b := to.GetPosition();
  290. IF a > b THEN t := a; a := b; b := t END;
  291. active := a # b
  292. END Sort;
  293. PROCEDURE SetText(text : Texts.UnicodeText);
  294. BEGIN
  295. IF text # NIL THEN SELF.text := text; NEW(from, text); NEW(to, text) END
  296. END SetText;
  297. END Highlight;
  298. HighlightArray = POINTER TO ARRAY OF Highlight;
  299. PositionMarker* = OBJECT
  300. VAR
  301. pos : Texts.TextPosition;
  302. img : WMGraphics.Image;
  303. str : String;
  304. color : WMGraphics.Color;
  305. hotX, hotY : LONGINT;
  306. currentArea : WMRectangles.Rectangle;
  307. ascent : LONGINT;
  308. text : Texts.UnicodeText;
  309. (* onChanged : WMMessages.CompCommand; *)
  310. visible : BOOLEAN;
  311. onChanged : PROCEDURE {DELEGATE} (sender, data: ANY);
  312. owner : TextObject;
  313. PROCEDURE SetOwner(owner : TextObject);
  314. BEGIN
  315. SELF.owner := owner;
  316. onChanged := owner.PositionMarkerChanged;
  317. END SetOwner;
  318. PROCEDURE &Init*;
  319. BEGIN
  320. color := LONGINT(0FF0000CCH); visible := TRUE
  321. END Init;
  322. PROCEDURE Draw(canvas : WMGraphics.Canvas; x, y, ascent : LONGINT);
  323. BEGIN
  324. IF ~visible THEN RETURN END;
  325. IF img # NIL THEN canvas.DrawImage(x - hotX, y - hotY, img, WMGraphics.ModeSrcOverDst)
  326. ELSE
  327. currentArea := GetArea(x, y, ascent);
  328. canvas.Fill(currentArea, LONGINT(0FF0000CCH), WMGraphics.ModeSrcOverDst)
  329. END
  330. END Draw;
  331. PROCEDURE GetArea(x, y, ascent : LONGINT) : WMRectangles.Rectangle;
  332. BEGIN
  333. IF img # NIL THEN RETURN WMRectangles.MakeRect(x - hotX, y - hotY, x - hotX + img.width, y - hotY + img.height)
  334. ELSE RETURN WMRectangles.MakeRect(x , y - ascent, x + 2, y)
  335. END
  336. END GetArea;
  337. PROCEDURE Load*(CONST filename : ARRAY OF CHAR);
  338. BEGIN
  339. img := WMGraphics.LoadImage(filename, TRUE);
  340. IF img # NIL THEN hotX := img.width DIV 2; hotY := img.height END;
  341. onChanged(SELF, NIL)
  342. END Load;
  343. PROCEDURE SetVisible*(visible : BOOLEAN);
  344. BEGIN
  345. IF SELF.visible # visible THEN
  346. SELF.visible := visible;
  347. onChanged(SELF, NIL)
  348. END
  349. END SetVisible;
  350. PROCEDURE SetPosition*(pos : LONGINT);
  351. BEGIN
  352. IF text = NIL THEN RETURN END; (* if no text is set, the position within is undef *)
  353. text.AcquireRead;
  354. IF pos # SELF.pos.GetPosition() THEN
  355. SELF.pos.SetPosition(pos);
  356. onChanged(SELF, NIL);
  357. END;
  358. text.ReleaseRead
  359. END SetPosition;
  360. PROCEDURE GetPosition*() : LONGINT;
  361. BEGIN
  362. RETURN pos.GetPosition()
  363. END GetPosition;
  364. PROCEDURE SetColor*(color : WMGraphics.Color);
  365. BEGIN
  366. IF SELF.color # color THEN
  367. SELF.color := color;
  368. onChanged(SELF, NIL)
  369. END
  370. END SetColor;
  371. PROCEDURE SetText(text : Texts.UnicodeText);
  372. BEGIN
  373. IF text # NIL THEN SELF.text := text; NEW(pos, text); END
  374. END SetText;
  375. END PositionMarker;
  376. PositionMarkerArray = POINTER TO ARRAY OF PositionMarker;
  377. TYPE TextDropTarget* = OBJECT(WMDropTarget.DropTarget);
  378. VAR text : Texts.Text;
  379. pos : Texts.TextPosition;
  380. PROCEDURE &New*(text : Texts.Text; pos : Texts.TextPosition);
  381. BEGIN
  382. SELF.text := text; SELF.pos := pos
  383. END New;
  384. (* PROCEDURE GetInterface*(type : LONGINT) : WMDropTarget.DropInterface;
  385. VAR di : WMDropTarget.DropText;
  386. BEGIN
  387. IF type = WMDropTarget.TypeText THEN
  388. NEW(di); di.text := text; di.pos := pos;
  389. RETURN di
  390. ELSE RETURN NIL
  391. END
  392. END GetInterface;
  393. *)
  394. END TextDropTarget;
  395. CONST
  396. vAlignTop = 0; vAlignCenter = 1; vAlignBottom = 2; vAlignJustified = 3;
  397. TYPE
  398. TextObject* = OBJECT(DTPData.ContentObject);
  399. VAR text : Texts.Text;
  400. properties: WMProperties.PropertyList;
  401. props: TextPropWindow;
  402. firstLine* : WMProperties.Int32Property;
  403. firstLineI* : LONGINT;
  404. firstPos* : LONGINT;
  405. firstIsFirstInP*: BOOLEAN;
  406. chainNext* : TextObject;
  407. chainPrev* : TextObject;
  408. chainNextN* : ARRAY 128 OF CHAR;
  409. chainPrevN* : ARRAY 128 OF CHAR;
  410. vAlign* : LONGINT;
  411. showBorders : BOOLEAN;
  412. bordersI, borderClip : WMRectangles.Rectangle;
  413. borders* : WMProperties.RectangleProperty;
  414. bounds* : WMProperties.RectangleProperty;
  415. layout : Layout;
  416. utilreader : Texts.TextReader; (* single process ! *)
  417. firstInParagraph: BOOLEAN;
  418. jSpaceSize : REAL;
  419. defaultTextColor*, defaultTextBgColor* : LONGINT;
  420. defaultAttr : Texts.Attributes;
  421. (* default style ?? *)
  422. defaultFont : WMGraphics.Font;
  423. fStyle : Texts.CharacterStyle;
  424. fZoom : REAL;
  425. (* wrapping *)
  426. wrap : SET;
  427. clipState : WMGraphics.CanvasState;
  428. defaultTabStops : TabStops;
  429. (* highlighting *)
  430. nofHighlights : LONGINT;
  431. highlights : HighlightArray;
  432. (* marked positions *)
  433. nofPositionMarkers : LONGINT;
  434. positionMarkers : PositionMarkerArray;
  435. cursor- : PositionMarker;
  436. selection- : Highlight;
  437. selecting : BOOLEAN;
  438. dragPossible : BOOLEAN;
  439. dragSelA, dragSelB : Texts.TextPosition;
  440. dragCopy : BOOLEAN;
  441. downX, downY : LONGINT;
  442. selectWords : BOOLEAN;
  443. wordSelOrdered : BOOLEAN;
  444. lineEnter : LONGINT;
  445. modifierFlags : SET;
  446. i : LONGINT;
  447. quality : BOOLEAN;
  448. preview : BOOLEAN;
  449. PROCEDURE &New*;
  450. BEGIN
  451. NEW(properties);
  452. NEW(props, SELF); vAlign := 0;
  453. NEW(firstLine, PTVfirstLine, NIL, NIL); properties.Add(firstLine);
  454. NEW(borders, PTVborders, NIL, NIL); properties.Add(borders);
  455. NEW(bounds, PTVbounds, NIL, NIL); properties.Add(bounds);
  456. NEW(layout);
  457. layout.layoutLineProc := LayoutLine;
  458. NEW(defaultAttr);
  459. NEW(defaultTabStops); defaultTabStops.tabDist := 20;
  460. NEW(highlights, 4); nofHighlights := 0;
  461. NEW(positionMarkers, 4); nofPositionMarkers := 0;
  462. NEW(text); SetText(text);
  463. cursor := CreatePositionMarker();
  464. showBorders := FALSE;
  465. selection := CreateHighlight();
  466. selection.kind := HLOver;
  467. selection.color := 0000FF80H;
  468. wrap := { WrapWord };
  469. (* properties *)
  470. (* firstLineI := 0; *)
  471. firstPos := 0;
  472. defaultTextColor := 0000000FFH;
  473. defaultTextBgColor := LONGINT(0FFFFFF00H);
  474. quality := TRUE;
  475. preview := FALSE;
  476. firstInParagraph := FALSE;
  477. (* RecacheProperties *)
  478. END New;
  479. PROCEDURE ClickHandler*(sender, data: ANY);
  480. BEGIN
  481. Redraw;
  482. END ClickHandler;
  483. PROCEDURE Clone*(): DTPData.ContentObject; (* clone all the current properties *)
  484. VAR newObj: TextObject;
  485. BEGIN
  486. NEW(newObj); newObj.contentName := Strings.NewString(contentName^);
  487. newObj.redrawProc := redrawProc; newObj.updatePropsPosition := updatePropsPosition;
  488. newObj.contentWidth := contentWidth; newObj.contentHeight := contentHeight; newObj.zoomFactor := zoomFactor;
  489. newObj.ownerDoc := ownerDoc;
  490. (* text specific clones *)
  491. text.AcquireRead;
  492. newObj.text.AcquireWrite;
  493. newObj.text.CopyFromText(text, 0, text.GetLength(), 0);
  494. newObj.text.ReleaseWrite;
  495. text.ReleaseRead;
  496. RETURN newObj;
  497. END Clone;
  498. PROCEDURE Invalidate;
  499. BEGIN
  500. Redraw;
  501. END Invalidate;
  502. PROCEDURE InvalidateRect(rect: WMRectangles.Rectangle);
  503. BEGIN
  504. Redraw;
  505. END InvalidateRect;
  506. PROCEDURE SetFocus*(focus: BOOLEAN);
  507. BEGIN
  508. SetFocus^(focus);
  509. Redraw;
  510. END SetFocus;
  511. PROCEDURE FocusLost*;
  512. BEGIN
  513. FocusLost^;
  514. cursor.SetVisible(FALSE);
  515. selection.SetFromTo(0, 0); Texts.ClearLastSelection;
  516. Redraw;
  517. END FocusLost;
  518. PROCEDURE FocusReceived*;
  519. BEGIN
  520. FocusReceived^;
  521. cursor.SetVisible(TRUE);
  522. Redraw;
  523. END FocusReceived;
  524. PROCEDURE GetPluginPointer*(): WMWindowManager.PointerInfo;
  525. VAR manager : WMWindowManager.WindowManager;
  526. BEGIN
  527. manager := WMWindowManager.GetDefaultManager();
  528. RETURN manager.pointerText;
  529. END GetPluginPointer;
  530. PROCEDURE BordersChanged;
  531. BEGIN
  532. borderClip := WMRectangles.MakeRect(bordersI.l, bordersI.t, bounds.GetWidth() - bordersI.r, bounds.GetHeight() - bordersI.b);
  533. layout.paperWidth := bounds.GetWidth() - (bordersI.l + bordersI.r);
  534. layout.FullLayout(firstPos, firstLineI); CheckNumberOfLines;
  535. END BordersChanged;
  536. PROCEDURE SetSize*(w, h: LONGINT);
  537. VAR obj: TextObject;
  538. BEGIN
  539. SetSize^(w, h);
  540. (* KernelLog.Int(w, 0); KernelLog.String(" : "); KernelLog.Int(h, 0); KernelLog.Ln; *)
  541. bounds.SetExtents(w, h);
  542. layout.paperWidth := bounds.GetWidth() - (bordersI.l + bordersI.r);
  543. borderClip.r := bounds.GetWidth() - bordersI.r; borderClip.b := bounds.GetHeight() - bordersI.b;
  544. layout.FullLayout(firstPos, firstLineI); CheckNumberOfLines;
  545. (* update frames in chain.. *)
  546. obj := chainNext;
  547. WHILE (obj # NIL) DO
  548. obj.Update;
  549. obj := obj.chainNext;
  550. END;
  551. END SetSize;
  552. PROCEDURE Resize*(zoom : REAL);
  553. BEGIN
  554. Resize^(zoom);
  555. (* layout.FullLayout; CheckNumberOfLines; *)
  556. (* Invalidate; *)
  557. END Resize;
  558. PROCEDURE ChainUpdate*;
  559. VAR obj: TextObject;
  560. BEGIN
  561. obj := chainNext;
  562. WHILE (obj # NIL) DO
  563. obj.Update;
  564. obj := obj.chainNext;
  565. END;
  566. END ChainUpdate;
  567. PROCEDURE Update*;
  568. BEGIN
  569. layout.FullLayout(firstPos, firstLineI); CheckNumberOfLines;
  570. Invalidate;
  571. END Update;
  572. (** Replace the text *)
  573. PROCEDURE SetText*(t : Texts.Text);
  574. VAR i : LONGINT;
  575. BEGIN
  576. ASSERT(t # NIL);
  577. (* Acquire; *)
  578. IF text # NIL THEN text.onTextChanged.Remove(TextChanged) END; (* unregister the TextChanged listener from the old text *)
  579. text := t;
  580. text.onTextChanged.Add(TextChanged); (* register the TextChanged listener with the new text*)
  581. NEW(utilreader, text);
  582. (* update all highlights *)
  583. FOR i := 0 TO nofHighlights - 1 DO highlights[i].SetText(text) END;
  584. FOR i := 0 TO nofPositionMarkers - 1 DO positionMarkers[i].SetText(text) END;
  585. layout.SetText(text);
  586. layout.FullLayout(firstPos, firstLineI);
  587. CheckNumberOfLines;
  588. (* Invalidate; *)
  589. (* Release *)
  590. END SetText;
  591. (* BEGIN highlighting *)
  592. PROCEDURE AddHighlight(highlight : Highlight);
  593. VAR newHighlights : HighlightArray; i : LONGINT;
  594. BEGIN
  595. INC(nofHighlights);
  596. IF nofHighlights > LEN(highlights) THEN
  597. NEW(newHighlights, LEN(highlights) * 2);
  598. FOR i := 0 TO LEN(highlights) - 1 DO newHighlights[i] := highlights[i] END;
  599. highlights := newHighlights;
  600. END;
  601. highlights[nofHighlights - 1] := highlight;
  602. HighlightChanged(NIL, NIL);
  603. END AddHighlight;
  604. PROCEDURE CreateHighlight*() : Highlight;
  605. VAR h : Highlight;
  606. BEGIN
  607. (* Acquire; *)
  608. NEW(h); h.SetText(text);
  609. h.onChanged := HighlightChanged;
  610. AddHighlight(h);
  611. (* Release; *)
  612. RETURN h
  613. END CreateHighlight;
  614. PROCEDURE RemoveHighlight*(x : Highlight);
  615. VAR i : LONGINT;
  616. BEGIN
  617. (* Acquire; *)
  618. i := 0; WHILE (i < nofHighlights) & (highlights[i] # x) DO INC(i) END;
  619. IF i < nofHighlights THEN
  620. WHILE (i < nofHighlights - 1) DO highlights[i] := highlights[i+1]; INC(i) END;
  621. DEC(nofHighlights);
  622. highlights[nofHighlights] := NIL
  623. END;
  624. HighlightChanged(NIL, NIL);
  625. (* Release *)
  626. END RemoveHighlight;
  627. PROCEDURE InvalidateRange(a, b : LONGINT);
  628. VAR t, l0, l1 : LONGINT; x0, y0, x1, y1, d : LONGINT;
  629. BEGIN
  630. IF a > b THEN t := a; a := b; b := t END;
  631. l0 := layout.FindLineNrByPos(a);
  632. l1 := layout.FindLineNrByPos(b);
  633. IF l0 = l1 THEN (* only one line... optimize *)
  634. LineYPos(l0, y0, y1);
  635. IF ~(FindScreenPos(a, x0, d) & FindScreenPos(b, x1, d)) THEN
  636. x0 := 0; x1 := bounds.GetWidth()
  637. END;
  638. InvalidateRect(WMRectangles.MakeRect(x0, y0, x1, y1));
  639. ELSE
  640. LineYPos(l0, y0, d); LineYPos(l1, d, y1);
  641. InvalidateRect(WMRectangles.MakeRect(0, y0, bounds.GetWidth(), y1));
  642. END;
  643. IF TraceInvalidate IN Trace THEN KernelLog.String("ir ") END;
  644. END InvalidateRange;
  645. PROCEDURE HighlightChanged(sender, data : ANY);
  646. VAR hl : Highlight; min, max : LONGINT;
  647. BEGIN
  648. text.AcquireRead;
  649. IF (sender # NIL) & (sender IS Highlight) THEN
  650. hl := sender(Highlight);
  651. IF (hl.oldFrom # hl.from.GetPosition()) & (hl.oldTo # hl.to.GetPosition()) THEN (* both changed *)
  652. min := MIN(
  653. MIN(hl.oldFrom, hl.from.GetPosition()),
  654. MIN(hl.oldTo, hl.to.GetPosition()));
  655. max := MAX(
  656. MAX(hl.oldFrom, hl.from.GetPosition()),
  657. MAX(hl.oldTo, hl.to.GetPosition()));
  658. InvalidateRange(min, max)
  659. ELSIF hl.oldTo # hl.to.GetPosition() THEN (* to changed *)
  660. InvalidateRange(hl.oldTo, hl.to.GetPosition())
  661. ELSIF hl.oldFrom # hl.from.GetPosition() THEN (* from changed *)
  662. InvalidateRange(hl.oldFrom, hl.from.GetPosition())
  663. ELSE (* position noch changed... probably color, style or visibility changed, invalidate range *)
  664. InvalidateRange(hl.from.GetPosition(),hl.to.GetPosition())
  665. END
  666. ELSE
  667. IF TraceInvalidate IN Trace THEN KernelLog.String("H") END;
  668. Invalidate
  669. END;
  670. text.ReleaseRead
  671. END HighlightChanged;
  672. (* END highlighting *)
  673. (* BEGIN PositionMarkers *)
  674. PROCEDURE AddPositionMarker(pm : PositionMarker);
  675. VAR newPositionMarkers : PositionMarkerArray; i : LONGINT;
  676. BEGIN
  677. INC(nofPositionMarkers);
  678. IF nofPositionMarkers > LEN(positionMarkers) THEN
  679. NEW(newPositionMarkers, LEN(positionMarkers) * 2);
  680. FOR i := 0 TO LEN(positionMarkers) - 1 DO newPositionMarkers[i] := positionMarkers[i] END;
  681. positionMarkers := newPositionMarkers
  682. END;
  683. positionMarkers[nofPositionMarkers - 1] := pm
  684. END AddPositionMarker;
  685. PROCEDURE CreatePositionMarker*() : PositionMarker;
  686. VAR p : PositionMarker;
  687. BEGIN
  688. (* Acquire; *)
  689. NEW(p); p.SetText(text);
  690. p.onChanged := PositionMarkerChanged;
  691. AddPositionMarker(p);
  692. (* Release; *)
  693. RETURN p
  694. END CreatePositionMarker;
  695. PROCEDURE RemovePositionMarker*(x : PositionMarker);
  696. VAR i, xp, yp, l : LONGINT; newRect : WMRectangles.Rectangle;
  697. BEGIN
  698. (* Acquire; *)
  699. i := 0; WHILE (i < nofPositionMarkers) & (positionMarkers[i] # x) DO INC(i) END;
  700. IF i < nofPositionMarkers THEN
  701. WHILE (i < nofPositionMarkers - 1) DO positionMarkers[i] := positionMarkers[i+1]; INC(i) END;
  702. DEC(nofPositionMarkers);
  703. positionMarkers[nofPositionMarkers] := NIL
  704. END;
  705. IF FindScreenPos(x.pos.GetPosition(), xp, yp) THEN
  706. l := layout.FindLineNrByPos(x.pos.GetPosition());
  707. IF (l < LEN(layout.lines^)) & (l >= 0) THEN
  708. newRect := x.GetArea(xp, yp, ENTIER(layout.lines[l].ascent));
  709. InvalidateRect(newRect)
  710. END
  711. END;
  712. (* Release *)
  713. END RemovePositionMarker;
  714. PROCEDURE PositionMarkerChanged(sender, data : ANY);
  715. VAR newRect, combinedRect : WMRectangles.Rectangle; x, y, l : LONGINT;
  716. BEGIN
  717. data := sender;
  718. IF (data # NIL) & (data IS PositionMarker) THEN
  719. IF data = cursor THEN CheckCursor END;
  720. text.AcquireRead;
  721. IF FindScreenPos(data(PositionMarker).pos.GetPosition(), x, y) THEN
  722. l := layout.FindLineNrByPos(data(PositionMarker).pos.GetPosition());
  723. (* KernelLog.String("Position: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  724. KernelLog.String("Line: "); KernelLog.Int(l, 0); KernelLog.Ln;
  725. *) IF (l < LEN(layout.lines^)) & (l >= 0) THEN
  726. newRect := data(PositionMarker).GetArea(x, y, ENTIER(layout.lines[l].ascent))
  727. END
  728. END;
  729. combinedRect := data(PositionMarker).currentArea;
  730. IF WMRectangles.RectEmpty(combinedRect) THEN combinedRect := newRect
  731. ELSE WMRectangles.ExtendRect(combinedRect, newRect)
  732. END;
  733. (* KernelLog.String("Posii+: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  734. *) IF ~WMRectangles.RectEmpty(combinedRect) THEN
  735. IF (WMRectangles.Area(data(PositionMarker).currentArea) + WMRectangles.Area(newRect)) * 5 < WMRectangles.Area(combinedRect) THEN
  736. (* KernelLog.String("Posii++: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  737. *) InvalidateRect(data(PositionMarker).currentArea);
  738. (* KernelLog.String("Posii+1: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  739. *) InvalidateRect(newRect);
  740. (* KernelLog.String("Posii+2: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  741. *) ELSE
  742. (* KernelLog.String("Posii+3: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  743. *) InvalidateRect(combinedRect);
  744. (* KernelLog.String("Posii+4: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  745. *) END
  746. END;
  747. text.ReleaseRead;
  748. ELSE
  749. (* KernelLog.String("Posii+5: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  750. *) Invalidate; KernelLog.String("Editor: XXX")
  751. END;
  752. (* KernelLog.String("Posii+++: "); KernelLog.Int(data(PositionMarker).pos.GetPosition(), 0); KernelLog.Ln;
  753. *)
  754. END PositionMarkerChanged;
  755. (* END PositionMarkers *)
  756. PROCEDURE CheckNumberOfLines;
  757. BEGIN
  758. firstLine.SetBounds(0, layout.GetNofLines() - 1)
  759. END CheckNumberOfLines;
  760. PROCEDURE CheckCursor;
  761. VAR cp, l, i : LONGINT; ty : REAL;
  762. BEGIN
  763. (* Scroll up, down to make cursor visible *)
  764. text.AcquireRead;
  765. cp := cursor.GetPosition();
  766. IF (cp < 0) THEN cursor.SetPosition(0)
  767. ELSIF (cp > text.GetLength()) THEN cursor.SetPosition(text.GetLength())
  768. END;
  769. l := layout.FindLineNrByPos(cursor.GetPosition());
  770. IF (l < firstLineI) THEN
  771. (* move the cursor down by 3 lines to get more context *)
  772. l := MAX(0, l - 3);
  773. firstLine.Set(l);
  774. ELSIF (l < layout.GetNofLines()) THEN
  775. ty := bordersI.t; i := firstLineI;
  776. WHILE i < l DO
  777. ty := ty + layout.lines[i].height; INC(i);
  778. IF layout.lines[i].firstInParagraph THEN ty := ty + layout.lines[i].spaceBefore; END;
  779. IF (i>0) & layout.lines[i-1].lastInParagraph THEN ty := ty + layout.lines[i-1].spaceAfter; END;
  780. END;
  781. ty := ty + layout.lines[i].height;
  782. IF ty >= bounds.GetHeight() - bordersI.b THEN
  783. l := MAX(0, l - 3);
  784. firstLine.Set(l)
  785. END
  786. END;
  787. text.ReleaseRead;
  788. (* Scroll left right to make cursor visible *)
  789. (* $$$ TODO *)
  790. END CheckCursor;
  791. PROCEDURE TextChanged(sender, data : ANY);
  792. VAR f, l, t, b, i, h: LONGINT; linesChanged : BOOLEAN;
  793. info : Texts.TextChangeInfo;
  794. realT, realB: REAL;
  795. BEGIN
  796. IF (data # NIL) & (data IS Texts.TextChangeInfo) & (data(Texts.TextChangeInfo).op # Texts.OpMulti) THEN
  797. text.AcquireRead;
  798. (* Acquire; *)
  799. info := data(Texts.TextChangeInfo);
  800. IF text.GetTimestamp() = info.timestamp THEN
  801. info := data(Texts.TextChangeInfo);
  802. IF info.op = Texts.OpInsert THEN layout.FixLayoutFrom(info.pos, info.len, f, l, linesChanged, firstPos, firstLineI)
  803. ELSE layout.FixLayoutFrom(info.pos, -info.len, f, l, linesChanged, firstPos, firstLineI)
  804. END;
  805. t := bordersI.t; realT := t;
  806. FOR i := firstLineI TO f - 1 DO
  807. realT := realT + (layout.lines[i].height);
  808. IF layout.lines[i].firstInParagraph THEN realT := realT + layout.lines[i].spaceBefore; END;
  809. IF (i>0) & layout.lines[i-1].lastInParagraph THEN realT := realT + layout.lines[i-1].spaceAfter; END;
  810. END;
  811. t := ENTIER(realT);
  812. h := bounds.GetHeight();
  813. IF linesChanged THEN b := h ELSE
  814. b := t; i := f;
  815. WHILE (i <= l) & (b < h) DO
  816. realB := realB + (layout.lines[i].height);
  817. IF layout.lines[i].firstInParagraph THEN realB := realB + layout.lines[i].spaceBefore; END;
  818. IF (i>0) & layout.lines[i-1].lastInParagraph THEN realB := realB + layout.lines[i-1].spaceAfter; END;
  819. INC(i);
  820. END;
  821. b := ENTIER(realB);
  822. END;
  823. CheckCursor; (* UpdateScrollbars; *)
  824. (* Release; *)
  825. InvalidateRect(WMRectangles.MakeRect(0, t, bounds.GetWidth(), b));
  826. ELSE
  827. IF TraceRenderOptimize IN Trace THEN KernelLog.String("Timestamp not equal ==> Complete re_layout"); KernelLog.Ln
  828. END;
  829. layout.FullLayout(firstPos, firstLineI);
  830. CheckCursor;
  831. (* InvalidateRect(GetClientRect()) *)
  832. Invalidate;
  833. END;
  834. text.ReleaseRead
  835. ELSE
  836. layout.FullLayout(firstPos, firstLineI);
  837. CheckCursor;
  838. (* InvalidateRect(GetClientRect()) *)
  839. Invalidate;
  840. END;
  841. CheckNumberOfLines;
  842. END TextChanged;
  843. (* BEGIN view dependant layout functions *)
  844. (** Return the left indent of a line - depending on alignment *)
  845. (* returns left border, in case of errors *)
  846. PROCEDURE GetLineLeftIndent(linenr : LONGINT): LONGINT;
  847. VAR result, boundsWidth: REAL;
  848. BEGIN
  849. IF (linenr < 0) OR (linenr >= layout.nofLines) THEN RETURN 0 END;
  850. (* KernelLog.Int(layout.lines[linenr].align, 0); *)
  851. (* KernelLog.String("bounds: "); KernelLog.Int(bounds.GetWidth(), 0); KernelLog.Ln; *)
  852. CASE layout.lines[linenr].align OF
  853. AlignLeft : result := 0;
  854. |AlignRight : IF layout.lines[linenr].lastInText THEN
  855. result := (bounds.GetWidth() - (layout.lines[linenr].width)+layout.lines[linenr].eotSize);
  856. ELSE
  857. result := (bounds.GetWidth() - (layout.lines[linenr].width)); (* + ENTIER(layout.lines[linenr].rightIndent) *)
  858. END;
  859. result := result - layout.lines[linenr].rightIndent;
  860. IF (layout.lines[linenr].pos = 0) OR (layout.lines[linenr].firstInParagraph) OR ((firstPos = layout.lines[linenr].pos) & firstIsFirstInP) THEN
  861. result := result - layout.lines[linenr].firstIndent;
  862. ELSE
  863. result := result - layout.lines[linenr].leftIndent;
  864. END;
  865. |AlignCenter : boundsWidth := bounds.GetWidth() - layout.lines[linenr].rightIndent;
  866. IF (layout.lines[linenr].pos = 0) OR (layout.lines[linenr].firstInParagraph) THEN
  867. boundsWidth := boundsWidth - layout.lines[linenr].firstIndent;
  868. ELSE
  869. boundsWidth := boundsWidth - layout.lines[linenr].leftIndent;
  870. END;
  871. IF layout.lines[linenr].lastInText THEN
  872. result := (boundsWidth - (layout.lines[linenr].width)+layout.lines[linenr].eotSize) / 2;
  873. ELSE
  874. result := (boundsWidth - (layout.lines[linenr].width)) / 2;
  875. END;
  876. ELSE
  877. result := 0;
  878. END;
  879. IF (layout.lines[linenr].pos = 0) OR (layout.lines[linenr].firstInParagraph) OR ((linenr>0) & layout.lines[linenr-1].lastInParagraph) OR ((firstPos = layout.lines[linenr].pos) & firstIsFirstInP)THEN
  880. result := result + layout.lines[linenr].firstIndent;
  881. (* KernelLog.String("firstIndent: "); DTPUtilities.OutReal(layout.lines[linenr].firstIndent, 4); KernelLog.Ln;
  882. KernelLog.String("line: "); KernelLog.Int(linenr, 0); KernelLog.Ln;
  883. *) ELSE
  884. result := result + layout.lines[linenr].leftIndent;
  885. END;
  886. RETURN ENTIER(result);
  887. END GetLineLeftIndent;
  888. (** Find the line number that currently contains the y value (y relative to 0 in component)*)
  889. PROCEDURE FindLineByY*(firstLine, y : LONGINT) : LONGINT;
  890. VAR i : LONGINT; ypos : REAL;
  891. BEGIN
  892. ypos := bordersI.t; i := firstLine;
  893. IF y < 0 THEN RETURN 0 END;
  894. WHILE (i < layout.nofLines) & (ypos <= y) DO
  895. ypos := ypos + layout.lines[i].height; INC(i);
  896. IF layout.lines[i].firstInParagraph THEN ypos := ypos + layout.lines[i].spaceBefore; END;
  897. IF (i>0) & layout.lines[i-1].lastInParagraph THEN ypos := ypos + layout.lines[i-1].spaceAfter; END;
  898. END;
  899. RETURN MAX(i -1, 0)
  900. END FindLineByY;
  901. PROCEDURE ViewToTextPos*(x, y: LONGINT; VAR pos : LONGINT);
  902. VAR l : LONGINT; dummy : LineInfo;
  903. boundsWidth : REAL;
  904. BEGIN
  905. text.AcquireRead;
  906. pos := -1;
  907. x := MAX(0, MIN(x, bounds.GetWidth()));
  908. y := MAX(0, MIN(y, bounds.GetHeight()));
  909. l := FindLineByY(firstLineI, MIN(MAX(y, bordersI.t), bounds.GetHeight() - bordersI.b));
  910. (* KernelLog.String("Line: "); KernelLog.Int(l, 0); KernelLog.Ln; *)
  911. x := x - bordersI.l; (* + leftShiftI; *)
  912. IF x < 0 THEN x := 0 END;
  913. dummy := layout.lines[l];
  914. IF l >= 0 THEN
  915. pos := layout.GetLineStartPos(l);
  916. IF dummy.align = 0 THEN
  917. IF (pos = 0) OR dummy.firstInParagraph THEN
  918. LayoutLine(pos, dummy, l,layout.paperWidth, -1, x-ENTIER(dummy.firstIndent), FALSE)
  919. ELSE
  920. LayoutLine(pos, dummy, l,layout.paperWidth, -1, x-ENTIER(dummy.leftIndent), FALSE)
  921. END;
  922. ELSIF dummy.align = 1 THEN
  923. boundsWidth := bounds.GetWidth() - dummy.rightIndent;
  924. IF dummy.lastInText THEN
  925. boundsWidth := boundsWidth - dummy.width + dummy.eotSize;
  926. ELSE
  927. boundsWidth := boundsWidth - dummy.width;
  928. END;
  929. IF (pos = 0) OR (dummy.firstInParagraph) THEN
  930. boundsWidth := boundsWidth - dummy.firstIndent;
  931. LayoutLine(pos, dummy, l, layout.paperWidth, -1, x-(ENTIER(boundsWidth)) DIV 2-ENTIER(dummy.firstIndent), FALSE);
  932. ELSE
  933. boundsWidth := boundsWidth - dummy.leftIndent;
  934. LayoutLine(pos, dummy, l, layout.paperWidth, -1, x-(ENTIER(boundsWidth)) DIV 2-ENTIER(dummy.leftIndent), FALSE);
  935. END;
  936. ELSIF dummy.align = 2 THEN
  937. boundsWidth := bounds.GetWidth() - dummy.rightIndent;
  938. IF dummy.lastInText THEN
  939. LayoutLine(pos, dummy, l, layout.paperWidth, -1, x-(ENTIER(boundsWidth)-(dummy.width)+dummy.eotSize), FALSE)
  940. ELSE
  941. LayoutLine(pos, dummy, l, layout.paperWidth, -1, x-(ENTIER(boundsWidth)-(dummy.width)), FALSE);
  942. END;
  943. ELSE
  944. jSpaceSize := dummy.spaceSize;
  945. IF (pos = 0) OR dummy.firstInParagraph THEN
  946. LayoutLine(pos, dummy, l,layout.paperWidth, -1, x-ENTIER(dummy.firstIndent), TRUE);
  947. ELSE
  948. LayoutLine(pos, dummy, l,layout.paperWidth, -1, x-ENTIER(dummy.leftIndent), TRUE);
  949. END;
  950. END;
  951. END;
  952. text.ReleaseRead;
  953. (* KernelLog.String("Pos: "); KernelLog.Int(pos, 0); KernelLog.Ln; *)
  954. END ViewToTextPos;
  955. (* END view dependant layout functions *)
  956. PROCEDURE GetFontFromAttr(info : Texts.FontInfo) : WMGraphics.Font;
  957. BEGIN
  958. RETURN WMGraphics.GetFont(info.name, info.size, info.style);
  959. END GetFontFromAttr;
  960. PROCEDURE GetFontFromStyle(VAR style : Texts.CharacterStyle) : WMGraphics.Font;
  961. VAR font : WMGraphics.Font;
  962. BEGIN
  963. IF (style.fontcache #NIL) & (style.fontcache IS WMGraphics.Font) THEN
  964. font := style.fontcache(WMGraphics.Font);
  965. ELSE
  966. font := WMGraphics.GetFont(style.family, ENTIER(DTPUtilities.FixpToFloat(style.size)), style.style);
  967. style.fontcache := font;
  968. END;
  969. RETURN font;
  970. END GetFontFromStyle;
  971. PROCEDURE LayoutLine(VAR pos : LONGINT; VAR l : LineInfo; linenr, wrapwidth, stopPos, stopXPos : LONGINT; justyfindcursor: BOOLEAN);
  972. VAR i, j, wrapPos: LONGINT; ch : Char32;
  973. f : WMGraphics.Font;
  974. eol, first, wrapped : BOOLEAN;
  975. voff, x, wrapX, align, nofSpaces: LONGINT;
  976. ascent, descent, realX, dx, realWX, a, d, spaceSize, spaceRSize: REAL;
  977. pStyle: Texts.ParagraphStyle;
  978. curStyle, cStyle: Texts.CharacterStyle;
  979. firstIndent, leftIndent, rightIndent, spaceBefore, spaceAfter, leading, leadi: REAL;
  980. PROCEDURE GetExtents(ch : Char32; VAR dx, ascentE, descentE: REAL);
  981. VAR gs : WMGraphics.GlyphSpacings; vc : WMComponents.VisualComponent;
  982. img : Image;
  983. BEGIN
  984. IF ch = Texts.ObjectChar THEN
  985. IF (utilreader.object # NIL) & (utilreader.object IS Image) THEN
  986. img := utilreader.object(Image);
  987. ascentE := (img.image.height*zoomFactor*point) - voff;
  988. (* KernelLog.String("ascent: "); DTPUtilities.OutReal(ascent, 4); KernelLog.Ln; *)
  989. descentE := voff;
  990. dx := (img.image.width*zoomFactor*point);
  991. leadi := (ascentE + descentE)+descent;
  992. ELSIF (utilreader.object # NIL) & (utilreader.object IS WMComponents.VisualComponent) THEN
  993. vc := utilreader.object(WMComponents.VisualComponent);
  994. dx := (vc.bounds.GetWidth()*zoomFactor*point);
  995. ascentE := (vc.bounds.GetHeight()*zoomFactor*point) - voff;
  996. descentE := voff;
  997. END
  998. ELSIF ch = Texts.TabChar THEN
  999. IF l.tabStops # NIL THEN dx := (l.tabStops.GetNextTabStop(ENTIER((x+1)/(zoomFactor*point)))*zoomFactor*point) - x
  1000. ELSE dx := (defaultTabStops.GetNextTabStop(ENTIER((x+1)/(zoomFactor*point)))*zoomFactor*point) - x
  1001. END;
  1002. ascentE := (f.GetAscent()*zoomFactor*point) - voff;
  1003. descentE := (f.GetDescent()*zoomFactor*point) + voff
  1004. ELSE
  1005. IF f.HasChar(ch) THEN
  1006. f.GetGlyphSpacings(ch, gs);
  1007. (* KernelLog.Int(f.GetAscent(), 0 ); KernelLog.Ln;
  1008. KernelLog.Int(f.GetDescent(), 0); KernelLog.Ln;
  1009. KernelLog.Int(voff, 0); KernelLog.Ln;
  1010. *) ascentE := (f.GetAscent()*zoomFactor*point) - voff;
  1011. descentE := (f.GetDescent()*zoomFactor*point) + voff;
  1012. (* KernelLog.Int(ch, 0); KernelLog.Ln; *)
  1013. ELSE
  1014. WMGraphics.FBGetGlyphSpacings(ch, gs);
  1015. ascentE := (gs.ascent*zoomFactor*point) - voff;
  1016. descentE := (gs.descent*zoomFactor*point) + voff;
  1017. (* KernelLog.String("FB: "); KernelLog.Int(ch, 0); KernelLog.Ln; *)
  1018. END;
  1019. dx := ((gs.bearing.l + gs.width + gs.bearing.r)*zoomFactor*point);
  1020. (* KernelLog.String("Size (dx): "); KernelLog.Int(dx, 0); KernelLog.Ln; *)
  1021. END
  1022. END GetExtents;
  1023. BEGIN
  1024. f := GetFont(); (* set the default component font *)
  1025. x := 0; realX := x;
  1026. l.pos := pos; l.height := ENTIER(f.GetHeight()*zoomFactor*point); eol := FALSE;
  1027. utilreader.SetDirection(1); utilreader.SetPosition(pos); first := TRUE; wrapped := FALSE;
  1028. i := 0; ascent := (f.GetAscent()*zoomFactor*point); descent := (f.GetDescent()*zoomFactor*point);
  1029. l.spaceBefore := 0; l.spaceAfter := 0; l.firstInParagraph := FALSE; l.lastInParagraph := FALSE;
  1030. leading := 0; leadi := 0; l.firstIndent := 0; firstIndent := 0; leftIndent := 0; rightIndent := 0;
  1031. nofSpaces := 0;
  1032. utilreader.ReadCh(ch);
  1033. IF utilreader.pstyle # NIL THEN (* Get ParagraphStyle *)
  1034. pStyle := utilreader.pstyle; (* reget style, because of some mysterious error*)
  1035. pStyle := Texts.GetParagraphStyleByName(pStyle.name);
  1036. spaceBefore := DTPUtilities.FixpToFloat(pStyle.spaceBefore)*zoomFactor;
  1037. spaceAfter := DTPUtilities.FixpToFloat(pStyle.spaceAfter)*zoomFactor;
  1038. firstIndent := DTPUtilities.FixpToFloat(pStyle.firstIndent)*zoomFactor;
  1039. leftIndent := DTPUtilities.FixpToFloat(pStyle.leftIndent)*zoomFactor;
  1040. rightIndent := DTPUtilities.FixpToFloat(pStyle.rightIndent)*zoomFactor;
  1041. align := pStyle.alignment;
  1042. (* KernelLog.String(pStyle.name); KernelLog.Ln;
  1043. DTPUtilities.OutReal(spaceBefore, 4); KernelLog.Ln;
  1044. DTPUtilities.OutReal(spaceAfter, 4); KernelLog.Ln;
  1045. DTPUtilities.OutReal(firstIndent, 4); KernelLog.Ln;
  1046. DTPUtilities.OutReal(leftIndent, 4); KernelLog.Ln;
  1047. DTPUtilities.OutReal(rightIndent, 4); KernelLog.Ln;
  1048. *) END;
  1049. IF (pos = 0) OR firstInParagraph OR ((linenr > 0) & layout.lines[linenr-1].lastInParagraph) OR ((firstPos = layout.lines[linenr].pos) & firstIsFirstInP)THEN
  1050. wrapwidth := ENTIER(wrapwidth - firstIndent - rightIndent);
  1051. (* KernelLog.String("firstIndent: "); DTPUtilities.OutReal(layout.lines[linenr].firstIndent, 4); KernelLog.Ln;
  1052. KernelLog.String("line: "); KernelLog.Int(linenr, 0); KernelLog.Ln;
  1053. *) ELSE
  1054. wrapwidth := ENTIER(wrapwidth - leftIndent - rightIndent);
  1055. END;
  1056. IF firstInParagraph OR ((linenr>0) &layout.lines[linenr-1].lastInParagraph) THEN
  1057. l.spaceBefore := spaceBefore;
  1058. l.firstInParagraph := TRUE;
  1059. firstInParagraph := FALSE;
  1060. (* l.firstIndent := firstIndent;
  1061. IF ~findCursor THEN
  1062. realX := firstIndent; x := ENTIER(realX);
  1063. END;
  1064. ELSIF pos = 0 THEN
  1065. l.firstIndent := firstIndent;
  1066. ELSE
  1067. l.firstIndent := 0;
  1068. IF ~findCursor THEN
  1069. realX := leftIndent; x := ENTIER(realX);
  1070. END;
  1071. *) END;
  1072. REPEAT
  1073. leadi := -1;
  1074. IF ~first THEN utilreader.ReadCh(ch); END;
  1075. IF utilreader.cstyle # NIL THEN (* Get CharacterStyle *)
  1076. cStyle := utilreader.cstyle;
  1077. voff := ENTIER(DTPUtilities.FixpToFloat(utilreader.cstyle.baselineShift)*zoomFactor*point);
  1078. leadi := DTPUtilities.FixpToFloat(cStyle.leading)*zoomFactor*point;
  1079. f := GetFontFromStyle(cStyle);
  1080. (* IF (cStyle.fontcache #NIL) & (cStyle.fontcache IS WMGraphics.Font) THEN
  1081. f := cStyle.fontcache(WMGraphics.Font);
  1082. ELSE
  1083. f := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1084. utilreader.cstyle.fontcache := f
  1085. END;
  1086. *)(* f := WMGraphics.GetFont(utilreader.cstyle.family, ENTIER(DTPUtilities.FixpToFloat(utilreader.cstyle.size)), utilreader.cstyle.style);
  1087. *) ELSIF (pStyle # NIL) & (pStyle.charStyle # NIL) THEN (* Get CharacterStyle from ParagraphStyle *)
  1088. cStyle := pStyle.charStyle;
  1089. voff := ENTIER(DTPUtilities.FixpToFloat(cStyle.baselineShift)*zoomFactor*point);
  1090. leadi := DTPUtilities.FixpToFloat(cStyle.leading)*zoomFactor*point;
  1091. f := GetFontFromStyle(cStyle);
  1092. (* IF (cStyle.fontcache #NIL) & (cStyle.fontcache IS WMGraphics.Font) THEN
  1093. f := cStyle.fontcache(WMGraphics.Font);
  1094. ELSE
  1095. f := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1096. utilreader.cstyle.fontcache := f
  1097. END;
  1098. *)(* f := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1099. *)
  1100. ELSIF utilreader.attributes # NIL THEN (* Get Attributes *)
  1101. voff := ENTIER(utilreader.attributes.voff*zoomFactor*point);
  1102. IF utilreader.attributes.fontInfo # NIL THEN
  1103. IF (utilreader.attributes.fontInfo.fontcache # NIL)
  1104. & (utilreader.attributes.fontInfo.fontcache IS WMGraphics.Font) THEN
  1105. f := utilreader.attributes.fontInfo.fontcache(WMGraphics.Font);
  1106. ELSE
  1107. f := GetFontFromAttr(utilreader.attributes.fontInfo);
  1108. utilreader.attributes.fontInfo.fontcache := f
  1109. END
  1110. ELSE f := GetFont()
  1111. END;
  1112. ELSE voff := 0; f := GetFont();
  1113. END;
  1114. IF first THEN
  1115. ascent := (f.GetAscent()*zoomFactor*point);
  1116. descent := (f.GetDescent()*zoomFactor*point); first := FALSE;
  1117. IF cStyle # NIL THEN leading := DTPUtilities.FixpToFloat(cStyle.leading)*zoomFactor*point ELSE leading := ascent + descent; END;
  1118. END;
  1119. INC(pos);
  1120. IF (stopPos < 0) OR (pos <= stopPos) THEN
  1121. IF ch # Texts.NewLineChar THEN
  1122. GetExtents(ch, dx, a, d);
  1123. (* KernelLog.String("Char: "); KernelLog.Int(ch, 0); KernelLog.Ln; *)
  1124. IF (ch = 32) THEN
  1125. INC(nofSpaces); DTPUtilities.Inc(spaceSize, dx);
  1126. IF justyfindcursor THEN dx := jSpaceSize; END;
  1127. (* KernelLog.String("space: "); DTPUtilities.OutReal(dx, 4); KernelLog.Ln; *)
  1128. (* KernelLog.String("nofSpaces: "); KernelLog.Int(nofSpaces, 0); KernelLog.Ln; *)
  1129. END;
  1130. IF (leadi = -1) THEN leadi := ascent + descent; END;
  1131. ascent := DTPUtilities.Max(ascent, a); descent := DTPUtilities.Max(descent, d);
  1132. leading := DTPUtilities.Max(leading, leadi);
  1133. IF (wrap # {}) & (i > 0) & (x + dx > wrapwidth) THEN
  1134. eol := TRUE; DEC(pos); wrapPos := pos;
  1135. (* Go left for last space *)
  1136. IF wrap * { WrapWord } # {} THEN
  1137. wrapped := TRUE;
  1138. pos := TextUtilities.FindPosWordLeft(utilreader, pos);
  1139. IF pos <= l.pos THEN pos := wrapPos END; (* no word break found. wrap at latest possible pos *)
  1140. END
  1141. ELSE
  1142. IF (stopXPos >= 0) & (x + ENTIER(dx) DIV 2 > stopXPos) THEN DEC(pos); RETURN END;
  1143. (* INC(x, dx) *)
  1144. DTPUtilities.Inc(realX, dx);
  1145. x := ENTIER(realX);
  1146. END;
  1147. ELSE eol := TRUE; IF (stopXPos >= 0) THEN DEC(pos) END;
  1148. l.lastInParagraph := TRUE;
  1149. l.spaceAfter := spaceAfter;
  1150. firstInParagraph := TRUE;
  1151. (* KernelLog.String("last in para.."); KernelLog.Ln; *)
  1152. END;
  1153. ELSE eol := TRUE
  1154. END;
  1155. INC(i)
  1156. UNTIL eol OR utilreader.eot;
  1157. (* KernelLog.String("Line width: "); KernelLog.Int(x, 3); KernelLog.Ln; *)
  1158. (* KernelLog.String("Real width: "); DTPUtilities.OutReal(realX, 4); KernelLog.Ln; *)
  1159. x := ENTIER(realX); (* Real Fix *)
  1160. IF utilreader.eot THEN (* EOT Fix *)
  1161. (* KernelLog.String("EOT: "); KernelLog.Int(ch, 0); KernelLog.String(" length: "); KernelLog.Int(dx, 0); KernelLog.Ln; *)
  1162. l.lastInText := TRUE;
  1163. l.eotSize := ENTIER(dx);
  1164. ELSE
  1165. l.lastInText := FALSE;
  1166. END;
  1167. IF wrapped THEN
  1168. i := pos - l.pos;
  1169. IF (i>1) THEN
  1170. wrapX := 0; realWX := 0; j := 0; utilreader.SetDirection(1); utilreader.SetPosition(l.pos);
  1171. (* KernelLog.String("startpos: "); KernelLog.Int(l.pos, 0); KernelLog.Ln; *)
  1172. WHILE (j <i-1) DO
  1173. utilreader.ReadCh(ch);
  1174. (* KernelLog.String("char: "); KernelLog.Int(ch, 0); KernelLog.Ln; *)
  1175. IF utilreader.pstyle # NIL THEN (* Get ParagraphStyle *)
  1176. pStyle := utilreader.pstyle;
  1177. END;
  1178. IF utilreader.cstyle # NIL THEN (* Get CharacterStyle *)
  1179. cStyle := utilreader.cstyle;
  1180. (* KernelLog.String("cstyle # NIL"); KernelLog.Ln; *)
  1181. voff := ENTIER(DTPUtilities.FixpToFloat(utilreader.cstyle.baselineShift)*zoomFactor*point);
  1182. IF curStyle # cStyle THEN
  1183. f := GetFontFromStyle(cStyle);
  1184. (* IF (cStyle.fontcache #NIL) & (cStyle.fontcache IS WMGraphics.Font) THEN
  1185. f := cStyle.fontcache(WMGraphics.Font);
  1186. ELSE
  1187. f := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1188. utilreader.cstyle.fontcache := f
  1189. END;
  1190. *)(* f := WMGraphics.GetFont(utilreader.cstyle.family, ENTIER(DTPUtilities.FixpToFloat(utilreader.cstyle.size)), utilreader.cstyle.style);
  1191. *) END;
  1192. curStyle := cStyle
  1193. ELSIF pStyle # NIL THEN (* Get CharacterStyle from ParagraphStyle *)
  1194. cStyle := pStyle.charStyle;
  1195. voff := ENTIER(DTPUtilities.FixpToFloat(cStyle.baselineShift)*zoomFactor*point);
  1196. IF curStyle # cStyle THEN
  1197. f := GetFontFromStyle(cStyle);
  1198. (* IF (cStyle.fontcache #NIL) & (cStyle.fontcache IS WMGraphics.Font) THEN
  1199. f := cStyle.fontcache(WMGraphics.Font);
  1200. ELSE
  1201. f := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1202. utilreader.cstyle.fontcache := f
  1203. END;
  1204. *)(* f := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1205. *) END;
  1206. curStyle := cStyle
  1207. ELSE voff := 0; f := GetFont();
  1208. END;
  1209. GetExtents(ch, dx, a, d);
  1210. IF (ch = 32) & justyfindcursor THEN dx := jSpaceSize; END;
  1211. (* KernelLog.String("adding: "); KernelLog.Int(dx, 0); KernelLog.Ln; *)
  1212. realWX := realWX + dx;
  1213. wrapX := ENTIER(wrapX + dx);
  1214. INC(j);
  1215. END;
  1216. l.width := ENTIER(realWX);
  1217. (* KernelLog.String("wrapped width: "); KernelLog.Int(wrapX, 0); KernelLog.Ln; *)
  1218. ELSE
  1219. l.width := x;
  1220. END;
  1221. (* KernelLog.Int(i, 0); KernelLog.String(":"); KernelLog.Int(x, 0); KernelLog.Ln; *)
  1222. ELSE l.width := x; END;
  1223. IF ~(l.lastInParagraph OR utilreader.eot) THEN
  1224. utilreader.SetDirection(1); utilreader.SetPosition(pos-1); utilreader.ReadCh(ch);
  1225. (* KernelLog.String("LastCharInLine: "); KernelLog.Int(ch, 0); KernelLog.Ln; *)
  1226. IF (ch = 32) THEN spaceRSize := (wrapwidth - l.width + spaceSize-(spaceSize/nofSpaces))/(nofSpaces-1);
  1227. ELSE spaceRSize := (wrapwidth - l.width + spaceSize)/(nofSpaces); END;
  1228. (* KernelLog.String("panelwidth: "); KernelLog.Int(wrapwidth, 0); KernelLog.Ln;
  1229. KernelLog.String("textwidth: "); KernelLog.Int(l.width, 0); KernelLog.Ln;
  1230. KernelLog.String("spacewidth: "); DTPUtilities.OutReal(spaceSize, 4); KernelLog.Ln;
  1231. KernelLog.String("nofSpaces: "); KernelLog.Int(nofSpaces, 0); KernelLog.Ln;
  1232. KernelLog.String("realSpaceWidth: "); DTPUtilities.OutReal(spaceRSize, 4); KernelLog.Ln;
  1233. *) END;
  1234. IF ~justyfindcursor THEN
  1235. IF (align = 3) THEN l.spaceSize := spaceRSize; ELSE l.spaceSize := 0; END;
  1236. END;
  1237. l.firstIndent := firstIndent; l.leftIndent := leftIndent; l.rightIndent := rightIndent; l.align := align;
  1238. l.ascent := ascent; l.height := leading; (* DTPUtilities.Max(leading, ascent + descent); *)
  1239. (* KernelLog.String("Height(ascent): "); DTPUtilities.OutReal(ascent, 4); KernelLog.Ln;
  1240. KernelLog.String("Height(descent): "); DTPUtilities.OutReal(descent, 4); KernelLog.Ln;
  1241. KernelLog.String("Size(height): "); DTPUtilities.OutReal(ascent + descent, 4); KernelLog.Ln;
  1242. KernelLog.String("Leading: "); DTPUtilities.OutReal(leading, 4); KernelLog.Ln;
  1243. *) IF l.height = 0 THEN l.height := (f.GetHeight()*zoomFactor*point) END;
  1244. (* KernelLog.Int(ascent + descent, 0); KernelLog.Int(l.align, 0); *)
  1245. END LayoutLine;
  1246. PROCEDURE LineYPos(lineNr : LONGINT; VAR y0, y1 : LONGINT);
  1247. VAR i : LONGINT;
  1248. realY0, realY1: REAL;
  1249. BEGIN
  1250. IF (lineNr >= firstLineI) & (lineNr < layout.GetNofLines()) THEN
  1251. y0 := bordersI.t; realY0:= y0; i := firstLineI;
  1252. WHILE i < lineNr DO
  1253. realY0 := realY0 + layout.lines[i].height; INC(i);
  1254. IF layout.lines[i].firstInParagraph THEN realY0 := realY0 + layout.lines[i].spaceBefore; END;
  1255. IF (i>0) & layout.lines[i-1].lastInParagraph THEN realY0 := realY0 + layout.lines[i-1].spaceAfter; END;
  1256. END;
  1257. realY1 := realY0 + layout.lines[i].height
  1258. ELSE realY0 := 0; realY1 := 0;
  1259. END;
  1260. y0 := ENTIER(realY0); y1 := ENTIER(realY1);
  1261. END LineYPos;
  1262. PROCEDURE FindScreenPos*(pos : LONGINT; VAR x, y : LONGINT) : BOOLEAN;
  1263. VAR l, i, startPos: LONGINT; ty : LONGINT; li : LineInfo; ch : Char32; lastLine : BOOLEAN;
  1264. f : WMGraphics.Font;
  1265. realTY: REAL;
  1266. BEGIN
  1267. text.AcquireRead;
  1268. lastLine := FALSE;
  1269. IF (pos = text.GetLength()) THEN
  1270. utilreader.SetDirection(1); utilreader.SetPosition(text.GetLength() - 1);
  1271. utilreader.ReadCh(ch);
  1272. IF ch = Texts.NewLineChar THEN lastLine := TRUE END
  1273. END;
  1274. IF lastLine THEN
  1275. ty := bordersI.t; realTY := ty; i := firstLineI;
  1276. WHILE i < layout.nofLines DO
  1277. realTY := realTY + layout.lines[i].height; INC(i);
  1278. IF layout.lines[i].firstInParagraph THEN realTY := realTY + layout.lines[i].spaceBefore; END;
  1279. IF (i>0) & layout.lines[i-1].lastInParagraph THEN realTY := realTY + layout.lines[i-1].spaceAfter; END;
  1280. END;
  1281. ty := ENTIER(realTY);
  1282. IF i > 0 THEN y := ENTIER(realTY + layout.lines[i - 1].ascent) ELSE y := (ty + 10) END;
  1283. x := bordersI.l; (* - leftShiftI; *)
  1284. text.ReleaseRead; RETURN TRUE
  1285. ELSIF (pos = 0) & (firstLineI = 0) THEN x := bordersI.l; f := GetFont(); y := f.GetAscent(); (* x := bordersI.l - leftShiftI; *)
  1286. text.ReleaseRead; RETURN TRUE
  1287. ELSE
  1288. l := layout.FindLineNrByPos(pos);
  1289. (* KernelLog.String("Pos: "); KernelLog.Int(pos, 0); KernelLog.Ln; *)
  1290. (* KernelLog.String("Line: "); KernelLog.Int(l, 0); KernelLog.Ln; *)
  1291. IF (l >= firstLineI) & (l < layout.GetNofLines()) THEN
  1292. realTY := bordersI.t; i := firstLineI;
  1293. WHILE i < l DO
  1294. realTY := realTY + layout.lines[i].height; INC(i);
  1295. IF layout.lines[i].firstInParagraph THEN realTY := realTY + layout.lines[i].spaceBefore; END;
  1296. IF (i>0) & layout.lines[i-1].lastInParagraph THEN realTY := realTY + layout.lines[i-1].spaceAfter; END;
  1297. END;
  1298. y := ENTIER(realTY + layout.lines[i].ascent);
  1299. startPos := layout.GetLineStartPos(i);
  1300. (* IF layout.lines[i].align = 0 THEN
  1301. LayoutLine(startPos, li, i,layout.paperWidth, pos, -1, FALSE);
  1302. x := (li.width + GetLineLeftIndent(l) + bordersI.l);
  1303. ELSIF layout.lines[i].align = 1 THEN
  1304. LayoutLine(startPos, li, i,layout.paperWidth, pos, -1, FALSE);
  1305. IF ~layout.lines[i].lastInParagraph THEN
  1306. IF layout.lines[i].firstInParagraph THEN
  1307. x := (li.width + GetLineLeftIndent(l) + bordersI.l- ENTIER(layout.lines[i].firstIndent));
  1308. ELSE
  1309. x := (li.width + GetLineLeftIndent(l) + bordersI.l- ENTIER(layout.lines[i].leftIndent));
  1310. END;
  1311. ELSE
  1312. x := (li.width + GetLineLeftIndent(l) + bordersI.l - ENTIER(layout.lines[i].leftIndent));
  1313. END;
  1314. ELSIF layout.lines[i].align = 2 THEN
  1315. LayoutLine(startPos, li, i,layout.paperWidth, pos, -1, FALSE);
  1316. IF ~layout.lines[i].lastInParagraph THEN
  1317. x := (li.width + GetLineLeftIndent(l) + bordersI.l - ENTIER(layout.lines[i].rightIndent));
  1318. ELSE
  1319. x := (li.width + GetLineLeftIndent(l) + bordersI.l - ENTIER(layout.lines[i].leftIndent));
  1320. END;
  1321. ELSE
  1322. LayoutLine(startPos, li, i,layout.paperWidth, pos, -1, FALSE);
  1323. x := (li.width + GetLineLeftIndent(l) + bordersI.l);
  1324. END;
  1325. *)
  1326. IF (layout.lines[i].align = 3) THEN
  1327. jSpaceSize := layout.lines[i].spaceSize;
  1328. LayoutLine(startPos, li, i,layout.paperWidth, pos, -1, TRUE);
  1329. (* KernelLog.String("finding justy position..."); DTPUtilities.OutReal(jSpaceSize, 4); KernelLog.Ln; *)
  1330. ELSE
  1331. LayoutLine(startPos, li, i,layout.paperWidth, pos, -1, FALSE);
  1332. END;
  1333. x := (li.width + GetLineLeftIndent(l) + bordersI.l);
  1334. (* - leftShiftI); *)
  1335. text.ReleaseRead; RETURN TRUE
  1336. ELSE
  1337. text.ReleaseRead; RETURN FALSE
  1338. END
  1339. END
  1340. END FindScreenPos;
  1341. (* llen = -1 to render until the end of line > 0 to render llen elements in the line *)
  1342. PROCEDURE RenderLine*(canvas : WMGraphics.Canvas; VAR l : LineInfo; linenr, top, llen : LONGINT);
  1343. VAR sx, x, sp, i, j, k, linelength, w, voff, color, bgcolor, p : LONGINT; char : Char32; gs: WMGraphics.GlyphSpacings;
  1344. curAttr : Texts.Attributes; font : WMGraphics.Font; vc : WMComponents.VisualComponent;
  1345. hc : BOOLEAN;
  1346. realX, dx: REAL;
  1347. curStyle, cStyle: Texts.CharacterStyle;
  1348. imh, imw: LONGINT;
  1349. BEGIN
  1350. font := GetFont();
  1351. ASSERT(defaultAttr # NIL);
  1352. curAttr := defaultAttr; canvas.SetColor(defaultAttr.color);
  1353. bgcolor := defaultAttr.bgcolor;
  1354. IF TraceRenderOptimize IN Trace THEN
  1355. KernelLog.String("RenderLine : "); KernelLog.Int(linenr, 5); KernelLog.String(" from position : ");
  1356. KernelLog.Int(layout.GetLineStartPos(linenr), 5); KernelLog.Ln;
  1357. END;
  1358. (* sp := layout.GetLineStartPos(linenr); *)
  1359. sp := l.pos;
  1360. IF sp >= text.GetLength() THEN RETURN END;
  1361. utilreader.SetDirection(1); utilreader.SetPosition(sp);
  1362. IF llen < 0 THEN linelength := layout.GetLineLength(linenr)
  1363. ELSE linelength := llen
  1364. END;
  1365. i := 0;
  1366. x := GetLineLeftIndent(linenr); realX := x;
  1367. (* KernelLog.String("start: "); KernelLog.Int(x, 0); KernelLog.Ln;
  1368. KernelLog.String("line: "); KernelLog.Int(linenr, 0); KernelLog.Ln;
  1369. IF l.pos = 0 THEN
  1370. realX := realX + layout.lines[linenr].firstIndent;
  1371. ELSE
  1372. IF layout.lines[linenr].align = 0 THEN
  1373. IF layout.lines[linenr].firstInParagraph THEN
  1374. realX := realX + layout.lines[linenr].firstIndent;
  1375. ELSE
  1376. realX := realX + layout.lines[linenr].leftIndent;
  1377. END;
  1378. ELSIF layout.lines[linenr].align = 2 THEN
  1379. realX := realX - layout.lines[linenr].rightIndent;
  1380. IF layout.lines[linenr].lastInParagraph THEN
  1381. realX := realX + layout.lines[linenr].leftIndent;
  1382. END;
  1383. ELSIF layout.lines[linenr].align = 3 THEN
  1384. IF layout.lines[linenr].firstInParagraph THEN
  1385. realX := realX + layout.lines[linenr].firstIndent;
  1386. ELSE
  1387. realX := realX + layout.lines[linenr].leftIndent;
  1388. END;
  1389. END;
  1390. END;
  1391. x := ENTIER(realX);
  1392. *)
  1393. sx := bordersI.l; (* sx := - leftShiftI + bordersI.l; *)
  1394. (* KernelLog.String("line: "); KernelLog.Int(linenr, 0); KernelLog.String(" width: "); KernelLog.Int(layout.lines[linenr].width, 3); KernelLog.String(" start: "); KernelLog.Int(x, 3); KernelLog.String(" bounds: "); KernelLog.Int(bounds.GetWidth(), 3); KernelLog.Ln;
  1395. *) IF TraceBaseLine IN Trace THEN
  1396. canvas.Line(0, top + ENTIER(l.ascent), bounds.GetWidth(), top + ENTIER(l.ascent), 01F0000FFH, WMGraphics.ModeCopy)
  1397. END;
  1398. w := bounds.GetWidth() - bordersI.r;
  1399. REPEAT
  1400. utilreader.ReadCh(char);
  1401. IF curAttr # utilreader.attributes THEN
  1402. IF utilreader.attributes # NIL THEN
  1403. (* Black is the default color *)
  1404. IF utilreader.attributes.color # 0FFH THEN canvas.SetColor(utilreader.attributes.color);
  1405. ELSE canvas.SetColor(defaultAttr.color)
  1406. END;
  1407. IF utilreader.attributes.fontInfo # NIL THEN
  1408. IF (utilreader.attributes.fontInfo.fontcache # NIL)
  1409. & (utilreader.attributes.fontInfo.fontcache IS WMGraphics.Font) THEN
  1410. font := utilreader.attributes.fontInfo.fontcache(WMGraphics.Font);
  1411. ELSE
  1412. font := GetFontFromAttr(utilreader.attributes.fontInfo);
  1413. utilreader.attributes.fontInfo.fontcache := font
  1414. END
  1415. ELSE font := GetFont()
  1416. END;
  1417. bgcolor := utilreader.attributes.bgcolor;
  1418. color := utilreader.attributes.color;
  1419. voff := utilreader.attributes.voff;
  1420. curAttr := utilreader.attributes
  1421. ELSE
  1422. IF curAttr # defaultAttr THEN
  1423. canvas.SetColor(defaultAttr.color);
  1424. bgcolor := defaultAttr.bgcolor;
  1425. voff := defaultAttr.voff;
  1426. color := defaultAttr.color;
  1427. curAttr := defaultAttr;
  1428. font := GetFont()
  1429. END
  1430. END;
  1431. END;
  1432. IF (utilreader.cstyle # NIL) THEN
  1433. cStyle := utilreader.cstyle;
  1434. IF (utilreader.pstyle # NIL) & (cStyle.name = "defaultCharacterStyle") THEN
  1435. IF utilreader.pstyle.charStyle # NIL THEN
  1436. cStyle := utilreader.pstyle.charStyle;
  1437. END;
  1438. END;
  1439. IF cStyle # curStyle THEN
  1440. font := GetFontFromStyle(cStyle);
  1441. (* IF (cStyle.fontcache #NIL) & (cStyle.fontcache IS WMGraphics.Font) THEN
  1442. font := cStyle.fontcache(WMGraphics.Font);
  1443. ELSE
  1444. font := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1445. utilreader.cstyle.fontcache := font
  1446. END;
  1447. *)(*  font := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1448. *) END;
  1449. curStyle := cStyle;
  1450. bgcolor := cStyle.bgColor;
  1451. color := cStyle.color;
  1452. voff := ENTIER(DTPUtilities.FixpToFloat(cStyle.baselineShift));
  1453. ELSIF utilreader.pstyle # NIL THEN
  1454. cStyle := utilreader.pstyle.charStyle;
  1455. IF cStyle # curStyle THEN
  1456. font := GetFontFromStyle(cStyle);
  1457. (* IF (cStyle.fontcache #NIL) & (cStyle.fontcache IS WMGraphics.Font) THEN
  1458. font := cStyle.fontcache(WMGraphics.Font);
  1459. ELSE
  1460. font := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1461. utilreader.cstyle.fontcache := font
  1462. END;
  1463. *)(* font := WMGraphics.GetFont(cStyle.family, ENTIER(DTPUtilities.FixpToFloat(cStyle.size)), cStyle.style);
  1464. *) END;
  1465. curStyle := cStyle;
  1466. bgcolor := cStyle.bgColor;
  1467. color := cStyle.color;
  1468. voff := ENTIER(DTPUtilities.FixpToFloat(cStyle.baselineShift));
  1469. ELSE
  1470. (* default values *)
  1471. color := 0000000FFH;
  1472. bgcolor := LONGINT(0FFFFFF00H);
  1473. font := WMGraphics.GetFont("Oberon", 12, {});
  1474. voff := 0;
  1475. curStyle := NIL
  1476. END;
  1477. IF char = Texts.ObjectChar THEN
  1478. IF (utilreader.object # NIL) & (utilreader.object IS Image) THEN
  1479. imh := utilreader.object(Image).image.height;
  1480. imw := utilreader.object(Image).image.width;
  1481. (* canvas.DrawImage(x, top + (l.ascent) + voff - utilreader.object(Image).height, utilreader.object(Image),
  1482. WMGraphics.ModeSrcOverDst); *)
  1483. canvas.ScaleImage(utilreader.object(Image).image, WMRectangles.MakeRect(0,0, imw, imh),
  1484. WMRectangles.MakeRect(x, top + ENTIER(l.ascent) + voff - ENTIER(imh*zoomFactor*point),
  1485. x + ENTIER(imw*zoomFactor*point), top + ENTIER(l.ascent) + voff),
  1486. WMRasterScale.ModeSrcOverDst, WMRasterScale.ScaleBox);
  1487. dx := imw*zoomFactor*point;
  1488. ELSIF (utilreader.object # NIL) & (utilreader.object IS WMComponents.VisualComponent) THEN
  1489. vc := utilreader.object(WMComponents.VisualComponent);
  1490. dx := (vc.bounds.GetWidth()*zoomFactor*point);
  1491. canvas.SaveState(clipState); (* save the current clip-state *)
  1492. canvas.SetClipRect(WMRectangles.MakeRect(x + sx, top, x + ENTIER(dx) + sx, top + ENTIER(l.height)));
  1493. canvas.ClipRectAsNewLimits(x + sx, top);
  1494. (* assuming the component will not delay --> otherwise a buffer is needed *)
  1495. vc.Acquire; vc.Draw(canvas); vc.Release;
  1496. canvas.RestoreState(clipState)
  1497. END
  1498. ELSIF char = 0 THEN (* EOT *)
  1499. ELSIF char = Texts.TabChar THEN
  1500. IF l.tabStops # NIL THEN dx := (l.tabStops.GetNextTabStop(ENTIER((x+1)/(zoomFactor*point)))*zoomFactor*point) - x
  1501. ELSE dx := (defaultTabStops.GetNextTabStop(ENTIER((x+1)/(zoomFactor*point)))*zoomFactor*point) - x
  1502. END;
  1503. (* KernelLog.String("drawing tab: "); DTPUtilities.OutReal(dx, 4); KernelLog.Ln; *)
  1504. IF bgcolor # 0FFFFFF00H THEN
  1505. canvas.Fill(WMRectangles.MakeRect(x + sx, top, x + ENTIER(dx) + sx, top + ENTIER(l.height)), bgcolor, WMGraphics.ModeCopy)
  1506. END
  1507. ELSE
  1508. IF char = Texts.NewLineChar THEN RETURN END;
  1509. hc := font.HasChar(char);
  1510. IF hc THEN font.GetGlyphSpacings(char, gs)
  1511. ELSE WMGraphics.FBGetGlyphSpacings(char, gs); END;
  1512. dx := ((gs.bearing.l + gs.width + gs.bearing.r)*zoomFactor*point);
  1513. IF bgcolor MOD 256 # 0 THEN
  1514. canvas.Fill(WMRectangles.MakeRect(x + sx, top, x + ENTIER(dx) + sx, top + ENTIER(l.height)), bgcolor, WMGraphics.ModeCopy)
  1515. END;
  1516. IF hc THEN
  1517. (* font.RenderChar(canvas, x + sx, top + (l.ascent) + voff, char) *)
  1518. IF curStyle # NIL THEN fStyle := curStyle END;
  1519. RenderChar(canvas, x + sx, top + ENTIER(l.ascent) + voff, char, font, color);
  1520. ELSE WMGraphics.FBRenderChar(canvas, x + sx, top + ENTIER(l.ascent) + voff, char)
  1521. END
  1522. END;
  1523. (* highlight *)
  1524. IF ~preview THEN
  1525. p := utilreader.GetPosition();
  1526. FOR j := 0 TO nofHighlights - 1 DO
  1527. IF (p > highlights[j].a) & (p <= highlights[j].b) THEN
  1528. CASE highlights[j].kind OF
  1529. |HLOver: canvas.Fill(WMGraphics.MakeRectangle(x + sx, top, x + ENTIER(dx) + sx+1, top + ENTIER(l.height)), highlights[j].color, WMGraphics.ModeSrcOverDst)
  1530. |HLUnder: canvas.Line(x + sx, top + ENTIER(l.ascent), x + ENTIER(dx) + sx+1, top + ENTIER(l.ascent), highlights[j].color, WMGraphics.ModeSrcOverDst);
  1531. |HLWave: FOR k := 0 TO ENTIER (dx) - 1 DO
  1532. canvas.SetPixel(x + k + sx, top + ENTIER(l.ascent) + (1 - ABS((x + k) MOD 4 - 2)), highlights[j].color, WMGraphics.ModeSrcOverDst);
  1533. END;
  1534. ELSE
  1535. END
  1536. END
  1537. END;
  1538. END;
  1539. IF (layout.lines[linenr].spaceSize # 0) & (char = 32) THEN realX := realX + layout.lines[linenr].spaceSize;
  1540. ELSE realX := realX + dx; END;
  1541. x := ENTIER(realX);
  1542. (* x := x + ENTIER(dx); *)
  1543. (* KernelLog.String("width: "); KernelLog.Int(x, 3); KernelLog.Ln;
  1544. KernelLog.String("real: "); DTPUtilities.OutReal(realX, 4); KernelLog.Ln;
  1545. *) INC(i)
  1546. UNTIL (i >= linelength) OR utilreader.eot OR (x + sx > w)
  1547. END RenderLine;
  1548. PROCEDURE RenderChar(canvas : WMGraphics.Canvas; x, y: REAL; char: Char32; font: WMGraphics.Font; color: LONGINT);
  1549. VAR g: WMGraphics.GlyphSpacings; img: WMGraphics.Image;
  1550. glyphCanvas: WMGraphics.BufferCanvas;
  1551. glyphImg: WMGraphics.Image;
  1552. mode : LONGINT;
  1553. curve : BOOLEAN;
  1554. BEGIN
  1555. (* IF (font IS WMOTFonts.Font) OR (font IS WMCCGFonts.Font) THEN
  1556. font := GetFontFromStyle(fStyle); curve := TRUE
  1557. ELSE
  1558. curve := FALSE;
  1559. END;
  1560. *)
  1561. font.GetGlyphSpacings(char, g);
  1562. font.GetGlyphMap(char, img);
  1563. IF img # NIL THEN
  1564. IF (glyphImg = NIL) OR (img.width > glyphImg.width) OR (img.height > glyphImg.height) THEN
  1565. NEW(glyphImg);
  1566. Raster.Create(glyphImg, img.width,img.height, Raster.BGRA8888);
  1567. NEW(glyphCanvas, glyphImg);
  1568. END;
  1569. glyphCanvas.SetColor(color);
  1570. glyphCanvas.DrawImage(0, 0,img, WMGraphics.ModeSrcOverDst);
  1571. IF ~quality THEN
  1572. mode := WMGraphics.ScaleBox;
  1573. ELSE
  1574. mode := WMGraphics.ScaleBilinear;
  1575. END;
  1576. (* canvas.DrawImage(ENTIER(x+g.bearing.l) + g.dx, ENTIER(y - font.ascent) +g.dy, img, WMGraphics.ModeSrcOverDst); *)
  1577. (* canvas.ScaleImage(img, WMRectangles.MakeRect(0,0, img.width, img.height), WMRectangles.MakeRect(ENTIER(x + g.bearing.l) + g.dx, ENTIER(y-font.ascent) + g.dy, ENTIER(x+g.bearing.l) + g.dx + ENTIER(img.width*zoomFactor*point), ENTIER(y - font.ascent) +g.dy + ENTIER(img.height*zoomFactor*point)), WMRasterScale.ModeSrcOverDst, WMRasterScale.ScaleBox); *)
  1578. IF curve THEN
  1579. canvas.DrawImage(ENTIER(x+g.bearing.l) + g.dx, ENTIER(y - font.ascent) +g.dy, img, WMGraphics.ModeSrcOverDst);
  1580. ELSE
  1581. canvas.ScaleImage(glyphImg, WMRectangles.MakeRect(0,0, img.width, img.height),
  1582. WMRectangles.MakeRect(ENTIER(x + (g.bearing.l + g.dx)*zoomFactor*point), ENTIER(y + (g.dy - font.ascent)*zoomFactor*point),
  1583. ENTIER(x + (g.bearing.l + g.dx)*zoomFactor*point) + ENTIER(img.width*zoomFactor*point), ENTIER(y + (g.dy - font.ascent)*zoomFactor*point) + ENTIER(img.height*zoomFactor*point)), WMRasterScale.ModeSrcOverDst, mode);
  1584. END;
  1585. END;
  1586. END RenderChar;
  1587. PROCEDURE RenderAboveTextMarkers*(canvas : WMGraphics.Canvas);
  1588. VAR x, y, l, pos, i, ascent : LONGINT;
  1589. BEGIN
  1590. (* AssertLock; *)
  1591. IF text = NIL THEN RETURN END;
  1592. IF ~preview THEN
  1593. text.AcquireRead;
  1594. FOR i := nofPositionMarkers - 1 TO 0 BY -1 DO
  1595. pos := positionMarkers[i].pos.GetPosition();
  1596. l := layout.FindLineNrByPos(pos);
  1597. IF FindScreenPos(pos, x, y) THEN
  1598. IF (l >= 0) & (l < layout.GetNofLines()) THEN ascent := ENTIER(layout.lines[l].ascent) ELSE ascent := 10 END;
  1599. positionMarkers[i].Draw(canvas, x, y, ascent);
  1600. END
  1601. END;
  1602. text.ReleaseRead;
  1603. END;
  1604. END RenderAboveTextMarkers;
  1605. PROCEDURE PointerDown*(x, y: LONGINT; keys: SET);
  1606. VAR pos, a, b : LONGINT; ch: Char32;
  1607. selectionText: Texts.Text;
  1608. from, to: Texts.TextPosition;
  1609. BEGIN
  1610. (* KernelLog.String("Pointer Down"); KernelLog.Ln; *)
  1611. IF (Inputs.Alt * modifierFlags # {}) & (0 IN keys) THEN (* copy attributes /style *)
  1612. text.AcquireWrite;
  1613. IF Texts.GetLastSelection(selectionText, from, to) THEN
  1614. selectionText.AcquireWrite;
  1615. a := MIN(from.GetPosition(), to.GetPosition());
  1616. b := MAX(from.GetPosition(), to.GetPosition());
  1617. ViewToTextPos(x, y, pos);
  1618. utilreader.SetPosition(pos);
  1619. utilreader.ReadCh(ch);
  1620. IF utilreader.cstyle # NIL THEN
  1621. selectionText.SetCharacterStyle(a, b - a, utilreader.cstyle);
  1622. ELSIF utilreader.attributes # NIL THEN
  1623. selectionText.SetAttributes(a, b - a, utilreader.attributes.Clone());
  1624. END;
  1625. selectionText.ReleaseWrite
  1626. END;
  1627. text.ReleaseWrite;
  1628. ELSIF 0 IN keys THEN (* left mouse button pressed *)
  1629. text.AcquireRead;
  1630. dragPossible := FALSE; selectWords := FALSE;
  1631. ViewToTextPos(x, y, pos);
  1632. (* KernelLog.String("Pos: "); KernelLog.Int(pos, 0); KernelLog.Ln;
  1633. KernelLog.String("X: "); KernelLog.Int(x, 0); KernelLog.Ln;
  1634. KernelLog.String("Y: "); KernelLog.Int(y, 0); KernelLog.Ln;
  1635. KernelLog.String("cursor: "); KernelLog.Int(cursor.GetPosition(), 0); KernelLog.Ln;
  1636. *) IF pos >= 0 THEN
  1637. (* KernelLog.Int(pos, 0); *)
  1638. selection.Sort;
  1639. (* clicking the same position twice --> Word Selection Mode *)
  1640. IF pos = cursor.GetPosition() THEN
  1641. selectWords := TRUE; wordSelOrdered := TRUE;
  1642. selection.SetFromTo(TextUtilities.FindPosWordLeft(utilreader, pos - 1),
  1643. TextUtilities.FindPosWordRight(utilreader, pos + 1))
  1644. ELSE
  1645. selection.SetFromTo(pos, pos) (* reset selection *)
  1646. END;
  1647. selecting := TRUE
  1648. END;
  1649. (* KernelLog.String("setting cursor to: "); KernelLog.Int(pos, 0); KernelLog.Ln;
  1650. *) cursor.SetPosition(pos);
  1651. (* KernelLog.String("cursor: "); KernelLog.Int(cursor.GetPosition(), 0); KernelLog.Ln;
  1652. *) text.ReleaseRead
  1653. END;
  1654. END PointerDown;
  1655. PROCEDURE PointerMove*(x, y: LONGINT; keys: SET);
  1656. VAR pos: LONGINT;
  1657. BEGIN
  1658. (*KernelLog.String("Pointer Move"); KernelLog.Ln; *)
  1659. IF selecting THEN
  1660. (* KernelLog.String("Selecting"); KernelLog.Ln; *)
  1661. text.AcquireRead;
  1662. ViewToTextPos(x, y, pos);
  1663. IF selecting THEN
  1664. IF selectWords THEN
  1665. IF pos < selection.from.GetPosition() THEN pos := TextUtilities.FindPosWordLeft(utilreader, pos - 1);
  1666. ELSE pos := TextUtilities.FindPosWordRight(utilreader, pos + 1)
  1667. END;
  1668. selection.SetTo(pos)
  1669. ELSE
  1670. selection.SetTo(pos);
  1671. END;
  1672. Texts.SetLastSelection(text, selection.from, selection.to);
  1673. cursor.SetPosition(pos);
  1674. StoreLineEnter;
  1675. END;
  1676. text.ReleaseRead
  1677. END;
  1678. (* KernelLog.Int(x, 0); KernelLog.String(" : "); KernelLog.Int(y, 0);KernelLog.Ln; *)
  1679. END PointerMove;
  1680. PROCEDURE PointerUp*(x, y: LONGINT; keys: SET);
  1681. BEGIN
  1682. (* KernelLog.String("Pointer Up (selecting = FALSE)"); KernelLog.Ln; *)
  1683. selecting := FALSE;
  1684. IF dragPossible THEN selection.SetFromTo(0, 0); Texts.ClearLastSelection (* reset selection *) END;
  1685. dragPossible := FALSE
  1686. END PointerUp;
  1687. PROCEDURE KeyEvent*(ucs: LONGINT; flags: SET; VAR keysym: LONGINT);
  1688. BEGIN
  1689. modifierFlags := flags;
  1690. (* KernelLog.String("KeyPressed"); KernelLog.Int(ucs, 0); KernelLog.Ln; *)
  1691. text.AcquireWrite;
  1692. IF keysym = 14H THEN (* Ctrl-T *)
  1693. text.CheckHealth
  1694. ELSIF keysym = 01H THEN (* Ctrl-A *)
  1695. SelectAll
  1696. ELSIF keysym = 03H THEN (* Ctrl-C *)
  1697. CopySelection
  1698. ELSIF (keysym = 0FF63H) & (flags * Inputs.Ctrl # {}) THEN (*Ctrl Insert *)
  1699. CopySelection
  1700. ELSIF keysym = 12H THEN (* Ctrl-R *)
  1701. layout.FullLayout(firstPos, firstLineI); Invalidate;CheckNumberOfLines;
  1702. KernelLog.String("Refreshed"); KernelLog.Ln;
  1703. ELSIF keysym = 0FF51H THEN (* Cursor Left *)
  1704. IF flags * Inputs.Alt # {} THEN IndentLeft
  1705. ELSE CursorLeft(flags * Inputs.Ctrl # {}, flags * Inputs.Shift # {})
  1706. END
  1707. ELSIF keysym = 0FF53H THEN (* Cursor Right *)
  1708. IF flags * Inputs.Alt # {} THEN IndentRight
  1709. ELSE CursorRight(flags * Inputs.Ctrl # {}, flags * Inputs.Shift # {})
  1710. END
  1711. ELSIF keysym = 0FF54H THEN (* Cursor Down *)
  1712. CursorDown(flags * Inputs.Shift # {})
  1713. ELSIF keysym = 0FF52H THEN (* Cursor Up *)
  1714. CursorUp(flags * Inputs.Shift # {})
  1715. ELSIF keysym = 0FF56H THEN (* Page Down *)
  1716. ELSIF keysym = 0FF55H THEN (* Page Up *)
  1717. ELSIF keysym = 0FF50H THEN (* Cursor Home *)
  1718. Home(flags * Inputs.Ctrl # {}, flags * Inputs.Shift # {})
  1719. ELSIF keysym = 0FF57H THEN (* Cursor End *)
  1720. End(flags * Inputs.Ctrl # {}, flags * Inputs.Shift # {})
  1721. ELSIF keysym = 016H THEN (* Ctrl-V *) Paste
  1722. ELSIF keysym = 018H THEN (* Ctrl-X *) CopySelection; DeleteSelection
  1723. ELSIF keysym = 0FFFFH THEN (* Delete *) Delete(flags)
  1724. ELSIF keysym = 0FF08H THEN (* Backspace *) Backspace(flags * Inputs.Ctrl # {})
  1725. ELSIF keysym = 0FF0DH THEN (* CR *) Enter(flags);
  1726. ELSIF (keysym = 0FF63H) & (flags * Inputs.Shift # {}) THEN (* Shift Insert *) Paste
  1727. (* ELSIF (keysym = 0FF1BH) THEN onEscape.Call(NIL); FocusNext (* Escape *) *)
  1728. ELSE
  1729. InsertChar(ucs);
  1730. IF text.GetLength() = 1 THEN
  1731. text.SetCharacterStyle(0,1, Texts.GetCharacterStyleByName("defaultCharacterStyle"));
  1732. text.SetParagraphStyle(0,1, Texts.GetParagraphStyleByName("defaultParagrahStyle"));
  1733. END;
  1734. END;
  1735. text.ReleaseWrite
  1736. END KeyEvent;
  1737. (* Drag away operations *)
  1738. PROCEDURE AutoStartDrag*;
  1739. VAR img : WMGraphics.Image;
  1740. c : WMGraphics.BufferCanvas;
  1741. w, h, i, la, lb, top : LONGINT;
  1742. l : LineInfo;
  1743. realH, realTop: REAL;
  1744. BEGIN
  1745. text.AcquireRead;
  1746. selection.Sort;
  1747. NEW(dragSelA, text);NEW(dragSelB, text);
  1748. dragSelA.SetPosition(selection.a); dragSelB.SetPosition(selection.b);
  1749. la := Limit(layout.FindLineNrByPos(selection.a), 0, layout.GetNofLines() - 1);
  1750. lb := Limit(layout.FindLineNrByPos(selection.b), 0, layout.GetNofLines() - 1);
  1751. (* estimate the size of the selection *)
  1752. h := 0; w := 0;
  1753. FOR i := la TO lb DO
  1754. realH := realH + (layout.lines[i].height);
  1755. w := ENTIER(DTPUtilities.Max(w, layout.lines[i].width));
  1756. END;
  1757. h := Limit(ENTIER(realH), 20, 200);
  1758. w := Limit(w, 20, 400);
  1759. (* render to bitmap *)
  1760. NEW(img); Raster.Create(img, w, h, Raster.BGRA8888);
  1761. NEW(c, img);
  1762. top := 0; realTop := top;
  1763. (* hack the startpos of the first line *)
  1764. l := layout.lines[la]; l.pos := selection.a;
  1765. IF la = lb THEN RenderLine(c, l, la, top, selection.b - selection.a)
  1766. ELSE
  1767. RenderLine(c, l, la, ENTIER(realTop), -1);
  1768. realTop := realTop + l.height;
  1769. END;
  1770. FOR i := la + 1 TO lb DO
  1771. IF i = lb THEN
  1772. RenderLine(c, layout.lines[i], i, ENTIER(realTop), selection.b - layout.lines[i].pos)
  1773. ELSE
  1774. RenderLine(c, layout.lines[i], i, top, -1);
  1775. realTop := realTop + (l.height)
  1776. END
  1777. END;
  1778. text.ReleaseRead;
  1779. (* IF StartDrag(NIL, img, DragWasAccepted, NIL) THEN
  1780. ELSE KernelLog.String("WMTextView : Drag could not be started")
  1781. END;
  1782. *) END AutoStartDrag;
  1783. PROCEDURE DragWasAccepted(sender, data : ANY);
  1784. VAR di : WMWindowManager.DragInfo;
  1785. dt : WMDropTarget.DropTarget;
  1786. (* itf : WMDropTarget.DropInterface;
  1787. res : WORD;
  1788. targetText, temp : Texts.Text;
  1789. pos, a, b : LONGINT; *)
  1790. BEGIN
  1791. IF (dragSelA = NIL) OR (dragSelB = NIL) THEN RETURN END;
  1792. IF (data # NIL) & (data IS WMWindowManager.DragInfo) THEN
  1793. di := data(WMWindowManager.DragInfo);
  1794. IF (di.data # NIL) & (di.data IS WMDropTarget.DropTarget) THEN
  1795. dt := di.data(WMDropTarget.DropTarget)
  1796. ELSE RETURN
  1797. END
  1798. ELSE RETURN
  1799. END;
  1800. (* itf := dt.GetInterface(WMDropTarget.TypeText);
  1801. IF itf # NIL THEN
  1802. targetText := itf(WMDropTarget.DropText).text;
  1803. IF targetText # NIL THEN
  1804. targetText.AcquireWrite;
  1805. IF ~dragCopy THEN
  1806. KernelLog.String("not copy"); KernelLog.Ln;
  1807. text.AcquireWrite;
  1808. a := dragSelA.GetPosition(); b := dragSelB.GetPosition();
  1809. pos := itf(WMDropTarget.DropText).pos.GetPosition();
  1810. IF (targetText # text) OR (pos < a) OR (pos > b) THEN
  1811. NEW(temp); temp.AcquireWrite; text.CopyToText(a, b- a, temp, 0); temp.ReleaseWrite;
  1812. text.Delete(a, b- a);
  1813. pos := itf(WMDropTarget.DropText).pos.GetPosition();
  1814. temp.AcquireRead; temp.CopyToText(0, temp.GetLength(), targetText, pos); temp.ReleaseRead;
  1815. END;
  1816. text.ReleaseWrite
  1817. ELSE
  1818. KernelLog.String("copy"); KernelLog.Ln;
  1819. text.AcquireRead;
  1820. pos := itf(WMDropTarget.DropText).pos.GetPosition();
  1821. a := dragSelA.GetPosition(); b := dragSelB.GetPosition();
  1822. text.CopyToText(a, b- a, targetText, pos);
  1823. text.ReleaseRead
  1824. END;
  1825. targetText.ReleaseWrite
  1826. END;
  1827. RETURN
  1828. END;
  1829. *) END DragWasAccepted;
  1830. (* Drag onto operations *)
  1831. PROCEDURE DragOver(x, y : LONGINT; dragInfo : WMWindowManager.DragInfo);
  1832. VAR pos : LONGINT;
  1833. BEGIN
  1834. text.AcquireRead;
  1835. ViewToTextPos(x, y, pos);
  1836. cursor.SetVisible(TRUE);
  1837. cursor.SetPosition(pos);
  1838. StoreLineEnter;
  1839. text.ReleaseRead
  1840. END DragOver;
  1841. PROCEDURE DragDropped*(x, y : LONGINT; dragInfo : WMWindowManager.DragInfo);
  1842. VAR dropTarget : TextDropTarget;
  1843. pos : LONGINT;
  1844. p : Texts.TextPosition;
  1845. BEGIN
  1846. text.AcquireRead;
  1847. ViewToTextPos(x, y, pos) ;
  1848. NEW(p, text); p.SetPosition(pos);
  1849. NEW(dropTarget, text, p);
  1850. text.ReleaseRead;
  1851. dragInfo.data := dropTarget;
  1852. (* ConfirmDrag(TRUE, dragInfo) *)
  1853. END DragDropped;
  1854. PROCEDURE InsertChar*(ch : Texts.Char32);
  1855. VAR buf : ARRAY 2 OF Texts.Char32;
  1856. BEGIN
  1857. buf[0] := ch; buf[1] := 0;
  1858. text.InsertUCS32(cursor.GetPosition(), buf) (* cursor moves automagically *)
  1859. END InsertChar;
  1860. PROCEDURE CopySelection*;
  1861. BEGIN
  1862. text.AcquireRead;
  1863. Texts.clipboard.AcquireWrite;
  1864. selection.Sort;
  1865. IF selection.b - selection.a > 0 THEN
  1866. (* clear the clipboard *)
  1867. IF Texts.clipboard.GetLength() > 0 THEN Texts.clipboard.Delete(0, Texts.clipboard.GetLength()) END;
  1868. Texts.clipboard.CopyFromText(text, selection.a, selection.b - selection.a, 0);
  1869. END;
  1870. Texts.clipboard.ReleaseWrite;
  1871. text.ReleaseRead
  1872. END CopySelection;
  1873. PROCEDURE DeleteSelection*;
  1874. BEGIN
  1875. text.AcquireWrite;
  1876. selection.Sort;
  1877. text.Delete(selection.a, selection.b - selection.a);
  1878. text.ReleaseWrite
  1879. END DeleteSelection;
  1880. PROCEDURE Paste*;
  1881. BEGIN
  1882. text.AcquireWrite;
  1883. Texts.clipboard.AcquireRead;
  1884. text.CopyFromText(Texts.clipboard, 0, Texts.clipboard.GetLength(), cursor.GetPosition());
  1885. Texts.clipboard.ReleaseRead;
  1886. text.ReleaseWrite
  1887. END Paste;
  1888. PROCEDURE Delete(flags : SET);
  1889. VAR pos : LONGINT;
  1890. BEGIN
  1891. pos := cursor.GetPosition();
  1892. (* shift delete *)
  1893. IF flags * Inputs.Shift # {} THEN
  1894. selection.Sort;
  1895. IF selection.active & (pos >= selection.a) & (pos <= selection.b) THEN
  1896. CopySelection
  1897. END;
  1898. END;
  1899. IF flags * Inputs.Ctrl # {} THEN
  1900. text.Delete(pos, TextUtilities.FindPosWordRight(utilreader, pos) - pos)
  1901. ELSE
  1902. selection.Sort;
  1903. IF selection.active & (pos >= selection.a) & (pos <= selection.b) THEN DeleteSelection
  1904. ELSE text.Delete(pos, 1)
  1905. END
  1906. END
  1907. END Delete;
  1908. PROCEDURE Backspace(word : BOOLEAN);
  1909. VAR pos, np : LONGINT;
  1910. BEGIN
  1911. pos := cursor.GetPosition();
  1912. IF word THEN
  1913. np := TextUtilities.FindPosWordLeft(utilreader, pos - 1);
  1914. text.Delete(np, pos - np)
  1915. ELSE
  1916. selection.Sort;
  1917. IF selection.active & (pos >= selection.a) & (pos <= selection.b) THEN DeleteSelection
  1918. ELSE text.Delete(pos - 1, 1)
  1919. END
  1920. END
  1921. END Backspace;
  1922. PROCEDURE Enter(flags : SET);
  1923. VAR pos, lineStart, nofWhitespace : LONGINT;
  1924. ctrl : BOOLEAN;
  1925. (* for call *)
  1926. BEGIN
  1927. ctrl := flags * Inputs.Ctrl # {};
  1928. IF ctrl THEN (* put into different module ??? *)
  1929. pos := cursor.GetPosition();
  1930. (* tv.StartCommand(pos); *)
  1931. ELSE
  1932. pos := cursor.GetPosition();
  1933. lineStart := TextUtilities.FindPosLineStart(utilreader, pos);
  1934. nofWhitespace := TextUtilities.CountWhitespace(utilreader, lineStart);
  1935. nofWhitespace := MIN(nofWhitespace, pos - lineStart);
  1936. InsertChar(Texts.NewLineChar);
  1937. IF nofWhitespace > 0 THEN
  1938. text.CopyFromText(text, lineStart, nofWhitespace, pos + 1)
  1939. END;
  1940. END;
  1941. (* onEnter.Call(NIL) *)
  1942. END Enter;
  1943. PROCEDURE IndentLeft;
  1944. BEGIN
  1945. text.AcquireWrite;
  1946. selection.Sort;
  1947. TextUtilities.IndentText(text, selection.a, selection.b, TRUE);
  1948. text.ReleaseWrite
  1949. END IndentLeft;
  1950. PROCEDURE IndentRight;
  1951. BEGIN
  1952. text.AcquireWrite;
  1953. selection.Sort;
  1954. TextUtilities.IndentText(text, selection.a, selection.b, FALSE);
  1955. text.ReleaseWrite
  1956. END IndentRight;
  1957. PROCEDURE SelectAll*;
  1958. BEGIN
  1959. text.AcquireRead;
  1960. selection.SetFromTo(0, text.GetLength());
  1961. Texts.SetLastSelection(text, selection.from, selection.to);
  1962. text.ReleaseRead
  1963. END SelectAll;
  1964. (* Prepare to start the selection by keyboard. Clear the selection, if it is not contigous *)
  1965. PROCEDURE KeyStartSelection(pos : LONGINT);
  1966. BEGIN
  1967. IF selection.to.GetPosition() # pos THEN selection.SetFromTo(pos, pos); Texts.ClearLastSelection END;
  1968. END KeyStartSelection;
  1969. (* update the keyboard selection with the new position, redraw from the last StartSelection *)
  1970. PROCEDURE KeyUpdateSelection(pos : LONGINT);
  1971. BEGIN
  1972. selection.SetTo(pos);
  1973. Texts.SetLastSelection(text, selection.from, selection.to)
  1974. END KeyUpdateSelection;
  1975. PROCEDURE CursorUp*(select : BOOLEAN);
  1976. VAR pos, cl : LONGINT;
  1977. BEGIN
  1978. text.AcquireRead;
  1979. pos := cursor.GetPosition();
  1980. IF select THEN KeyStartSelection(pos)
  1981. ELSE selection.SetFromTo(cursor.GetPosition(), cursor.GetPosition()); Texts.ClearLastSelection
  1982. END;
  1983. cl := layout.FindLineNrByPos(pos);
  1984. IF cl > 0 THEN
  1985. DEC(cl);
  1986. cursor.SetPosition(layout.GetLineStartPos(cl) + MIN(layout.GetLineLength(cl) - 1, lineEnter));
  1987. IF cl < firstLineI THEN firstLine.Set(cl) END
  1988. END;
  1989. IF select THEN KeyUpdateSelection(cursor.GetPosition()) END;
  1990. text.ReleaseRead
  1991. END CursorUp;
  1992. PROCEDURE CursorDown*(select : BOOLEAN);
  1993. VAR pos, cl : LONGINT;
  1994. BEGIN
  1995. text.AcquireRead;
  1996. pos := cursor.GetPosition();
  1997. IF select THEN KeyStartSelection(pos)
  1998. ELSE selection.SetFromTo(cursor.GetPosition(), cursor.GetPosition()); Texts.ClearLastSelection
  1999. END;
  2000. cl := layout.FindLineNrByPos(pos);
  2001. IF cl < layout.GetNofLines() - 1 THEN
  2002. INC(cl);
  2003. cursor.SetPosition(layout.GetLineStartPos(cl) + MIN(layout.GetLineLength(cl) - 1, lineEnter));
  2004. IF cl > FindLineByY(firstLineI, bounds.GetHeight() - bordersI.b) THEN firstLine.Set(firstLineI + 1 ) END
  2005. END;
  2006. IF select THEN KeyUpdateSelection(cursor.GetPosition()) END;
  2007. text.ReleaseRead
  2008. END CursorDown;
  2009. (* Move the cursor one character/word to the left *)
  2010. PROCEDURE CursorLeft*(word, select : BOOLEAN);
  2011. BEGIN
  2012. text.AcquireRead;
  2013. IF select THEN KeyStartSelection(cursor.GetPosition())
  2014. ELSE selection.SetFromTo(cursor.GetPosition(), cursor.GetPosition()); Texts.ClearLastSelection
  2015. END;
  2016. IF ~ word THEN cursor.SetPosition(cursor.GetPosition() - 1)
  2017. ELSE cursor.SetPosition(TextUtilities.FindPosWordLeft(utilreader, cursor.GetPosition() - 1))
  2018. END;
  2019. IF select THEN KeyUpdateSelection(cursor.GetPosition()) END;
  2020. StoreLineEnter;
  2021. text.ReleaseRead
  2022. END CursorLeft;
  2023. (* Move the cursor one character/word to the right *)
  2024. PROCEDURE CursorRight*(word, select : BOOLEAN);
  2025. BEGIN
  2026. text.AcquireRead;
  2027. IF select THEN KeyStartSelection(cursor.GetPosition())
  2028. ELSE selection.SetFromTo(cursor.GetPosition(), cursor.GetPosition()); Texts.ClearLastSelection
  2029. END;
  2030. IF ~ word THEN cursor.SetPosition(cursor.GetPosition() + 1)
  2031. ELSE cursor.SetPosition(TextUtilities.FindPosWordRight(utilreader, cursor.GetPosition() + 1))
  2032. END;
  2033. IF select THEN KeyUpdateSelection(cursor.GetPosition()) END;
  2034. StoreLineEnter;
  2035. text.ReleaseRead
  2036. END CursorRight;
  2037. PROCEDURE Home*(ctrl, select : BOOLEAN);
  2038. VAR cl : LONGINT;
  2039. BEGIN
  2040. text.AcquireRead;
  2041. IF select THEN KeyStartSelection(cursor.GetPosition())
  2042. ELSE selection.SetFromTo(cursor.GetPosition(), cursor.GetPosition()); Texts.ClearLastSelection
  2043. END;
  2044. IF ctrl THEN cursor.SetPosition(0); firstLine.Set(0)
  2045. ELSE cl := layout.FindLineNrByPos(cursor.GetPosition());
  2046. cursor.SetPosition(layout.GetLineStartPos(cl))
  2047. END;
  2048. StoreLineEnter;
  2049. IF select THEN KeyUpdateSelection(cursor.GetPosition()) END;
  2050. text.ReleaseRead
  2051. END Home;
  2052. PROCEDURE End*(ctrl, select : BOOLEAN);
  2053. VAR cl : LONGINT;
  2054. BEGIN
  2055. text.AcquireRead;
  2056. IF select THEN KeyStartSelection(cursor.GetPosition())
  2057. ELSE selection.SetFromTo(cursor.GetPosition(), cursor.GetPosition()); Texts.ClearLastSelection
  2058. END;
  2059. IF ctrl THEN cursor.SetPosition(text.GetLength()); firstLine.Set(layout.FindLineNrByPos(text.GetLength()))
  2060. ELSE cl := layout.FindLineNrByPos(cursor.GetPosition());
  2061. cursor.SetPosition(layout.GetLineStartPos(cl) + layout.GetLineLength(cl) - 1)
  2062. END;
  2063. StoreLineEnter;
  2064. IF select THEN KeyUpdateSelection(cursor.GetPosition()) END;
  2065. text.ReleaseRead
  2066. END End;
  2067. PROCEDURE Draw*(canvas : WMGraphics.Canvas; x, y, w, h : LONGINT; zoomF: REAL; quality, preview: BOOLEAN);
  2068. VAR la, lb, i, top, t : LONGINT; cliprect : WMRectangles.Rectangle; cstate : WMGraphics.CanvasState;
  2069. color: LONGINT;
  2070. realTop: REAL;
  2071. overflow: BOOLEAN;
  2072. chained: BOOLEAN;
  2073. newText: Texts.Text;
  2074. BEGIN
  2075. overflow := FALSE; INC(y, 1);
  2076. IF chainNext # NIL THEN chained := TRUE; ELSE chained := FALSE; END;
  2077. SELF.quality := quality;
  2078. SELF.preview := preview;
  2079. zoomFactor := zoomF;
  2080. ASSERT(layout # NIL);
  2081. canvas.SaveState(cstate);
  2082. canvas.ClipRectAsNewLimits(x, y);
  2083. canvas.GetClipRect(cliprect);
  2084. IF WMRectangles.RectEmpty(cliprect) THEN RETURN END;
  2085. (* color := 0BBBBBBFFH;
  2086. canvas.Fill(WMRectangles.MakeRect(0, 0, 0+w+1, 0+h+1), color, WMGraphics.ModeCopy);
  2087. color := 000FF00FFH;
  2088. canvas.Line(0, 0, 0+w, 0+h, color, WMGraphics.ModeCopy);
  2089. canvas.Line(0+w, 0, 0, 0+h, color, WMGraphics.ModeCopy);
  2090. *)
  2091. IF showBorders THEN
  2092. WMGraphicUtilities.DrawBevel(canvas, WMRectangles.ResizeRect(bounds.Get(), -1),
  2093. 1, TRUE, LONGINT(0808080FFH), WMGraphics.ModeCopy)
  2094. END;
  2095. text.AcquireRead;
  2096. la := FindLineByY(firstLineI, MAX(cliprect.t, bordersI.t));
  2097. lb := FindLineByY(firstLineI, MIN(cliprect.b, bounds.GetHeight() - bordersI.b));
  2098. (* KernelLog.String("FrameHeight: "); KernelLog.Int(h, 0); KernelLog.Ln; *)
  2099. (* KernelLog.String("bounds Height: "); KernelLog.Int(bounds.GetHeight(), 0); KernelLog.Ln; *)
  2100. (* allow clean clipping in at inner border *)
  2101. WMRectangles.ClipRect(cliprect, borderClip);
  2102. canvas.SetClipRect(cliprect);
  2103. (* prepare selections *)
  2104. FOR i := 0 TO nofHighlights - 1 DO
  2105. highlights[i].a := highlights[i].from.GetPosition();
  2106. highlights[i].b := highlights[i].to.GetPosition();
  2107. IF highlights[i].a > highlights[i].b THEN t := highlights[i].a; highlights[i].a := highlights[i].b; highlights[i].b := t END
  2108. END;
  2109. top := bordersI.t; realTop := top;
  2110. FOR i := firstLineI TO la - 1 DO
  2111. realTop := realTop + (layout.lines[i].height);
  2112. IF layout.lines[i].firstInParagraph THEN realTop := realTop + layout.lines[i].spaceBefore; END;
  2113. IF layout.lines[i].lastInParagraph THEN realTop := realTop + layout.lines[i].spaceAfter; END;
  2114. END;
  2115. IF la >= 0 THEN
  2116. (* draw the lines that intersect the clipping rectangle *)
  2117. FOR i := la TO lb DO
  2118. IF (layout.lines[i].firstInParagraph) & (i # firstLineI) THEN realTop := realTop + layout.lines[i].spaceBefore; END;
  2119. IF ~(ENTIER(realTop + (layout.lines[i].height)) > h) THEN
  2120. RenderLine(canvas, layout.lines[i], i, ENTIER(realTop), -1);
  2121. IF layout.lines[i].lastInParagraph & (ENTIER(realTop +(layout.lines[i].spaceAfter)) > h) & chained THEN
  2122. (* chainNext.firstLineI := i+1; *)
  2123. chainNext.firstLine.Set(i+1);
  2124. chainNext.firstPos := layout.lines[i+1].pos;
  2125. IF layout.lines[i].lastInParagraph THEN chainNext.firstIsFirstInP := TRUE ELSE chainNext.firstIsFirstInP := FALSE END;
  2126. IF chainNext.text # text THEN chainNext.SetText(text); END;
  2127. i := lb;
  2128. ELSIF chained & (layout.GetNofLines() < lb+2) THEN
  2129. NEW(newText); chainNext.SetText(newText);
  2130. (* chainNext.firstLineI := 0; *)
  2131. chainNext.firstLine.Set(0);
  2132. chainNext.firstPos := 0;
  2133. END;
  2134. ELSE
  2135. IF chained THEN
  2136. (* chainNext.firstLineI := i; *)
  2137. chainNext.firstLine.Set(i);
  2138. chainNext.firstPos := layout.lines[i].pos;
  2139. IF (i>0) & layout.lines[i-1].lastInParagraph THEN chainNext.firstIsFirstInP := TRUE ELSE chainNext.firstIsFirstInP := FALSE END;
  2140. IF chainNext.text # text THEN chainNext.SetText(text); END;
  2141. END;
  2142. i := lb;
  2143. END;
  2144. realTop := realTop + (layout.lines[i].height);
  2145. IF layout.lines[i].lastInParagraph THEN realTop := realTop + layout.lines[i].spaceAfter; END;
  2146. (* KernelLog.String("TextHeight: "); KernelLog.Int(ENTIER(realTop), 0); KernelLog.Ln; *)
  2147. IF (ENTIER(realTop) > h) THEN overflow := TRUE; END;
  2148. END
  2149. END;
  2150. IF (overflow OR (layout.GetNofLines() > lb+1)) & ~preview THEN
  2151. (* KernelLog.String("lines: "); KernelLog.Int(layout.GetNofLines(), 0); KernelLog.Ln;
  2152. KernelLog.String("lb: "); KernelLog.Int(lb, 0); KernelLog.Ln;
  2153. *) IF chained THEN color := 000FF00FFH;
  2154. ELSE color := LONGINT(0FF0000FFH); END;
  2155. canvas.Line(w-6, h-6, w, h-6, color, WMGraphics.ModeCopy);
  2156. canvas.Line(w-6, h-6, w-6, h, color, WMGraphics.ModeCopy);
  2157. canvas.Line(w-6, h, w, h, color, WMGraphics.ModeCopy);
  2158. canvas.Line(w, h-6, w, h, color, WMGraphics.ModeCopy);
  2159. canvas.Line(w-4, h-3, w-2, h-3, color, WMGraphics.ModeCopy);
  2160. canvas.Line(w-3, h-4, w-3, h-2, color, WMGraphics.ModeCopy);
  2161. END;
  2162. RenderAboveTextMarkers(canvas);
  2163. text.ReleaseRead;
  2164. canvas.RestoreState(cstate);
  2165. (* canvas.SaveState(canvasState);
  2166. canvas.ClipRectAsNewLimits(x, y);
  2167. canvas.RestoreState(canvasState);
  2168. *) END Draw;
  2169. PROCEDURE Redraw*;
  2170. BEGIN
  2171. Redraw^;
  2172. END Redraw;
  2173. PROCEDURE StoreLineEnter;
  2174. VAR pos, cl : LONGINT;
  2175. BEGIN
  2176. pos := cursor.GetPosition();
  2177. cl := layout.FindLineNrByPos(pos);
  2178. lineEnter := pos - layout.GetLineStartPos(cl)
  2179. END StoreLineEnter;
  2180. PROCEDURE GetFont(): WMGraphics.Font;
  2181. BEGIN
  2182. IF defaultFont = NIL THEN
  2183. RETURN WMGraphics.GetDefaultFont();
  2184. ELSE
  2185. RETURN defaultFont;
  2186. END;
  2187. END GetFont;
  2188. PROCEDURE OnDelete*;
  2189. VAR textObj, tempObj : TextObject;
  2190. text: Texts.Text;
  2191. BEGIN
  2192. IF (chainPrev # NIL) THEN (* remove chain from prev frame *)
  2193. chainPrev.chainNext := NIL;
  2194. END;
  2195. IF (chainNext # NIL) THEN (* remove whole chain in chain *)
  2196. textObj := chainNext; chainNext := NIL; chainPrev := NIL;
  2197. WHILE (textObj # NIL) DO
  2198. tempObj := textObj.chainNext;
  2199. textObj.chainPrev := NIL;
  2200. textObj.chainNext := NIL;
  2201. NEW(text);
  2202. textObj.SetText(text);
  2203. textObj.firstPos := 0; textObj.firstLineI := 0; textObj.firstLine.Set(0);
  2204. textObj := tempObj;
  2205. END;
  2206. END;
  2207. END OnDelete;
  2208. PROCEDURE Load*(elem: XML.Element);
  2209. VAR str : Strings.String;
  2210. node, para, span, tc: XMLObjects.Enumerator;
  2211. ptr: ANY;
  2212. text: Texts.Text;
  2213. pstyle : Texts.ParagraphStyle;
  2214. cstyle : Texts.CharacterStyle;
  2215. len : LONGINT;
  2216. attr: Texts.Attributes;
  2217. fonti: Texts.FontInfo;
  2218. done: BOOLEAN;
  2219. img: Image;
  2220. image: WMGraphics.Image;
  2221. obj: Texts.ObjectPiece;
  2222. PROCEDURE GetUTF8Char(r : Streams.Reader; VAR u : Texts.Char32; VAR pos : LONGINT) : BOOLEAN;
  2223. VAR ch : ARRAY 8 OF CHAR; i : LONGINT;
  2224. BEGIN
  2225. ch[0] := r.Get(); INC(pos);
  2226. FOR i := 1 TO ORD(UTF8Strings.CodeLength[ORD(ch[0])]) - 1 DO ch[i] := r.Get(); INC(pos) END;
  2227. i := 0;
  2228. RETURN UTF8Strings.DecodeChar(ch, i, u)
  2229. END GetUTF8Char;
  2230. PROCEDURE InsertPiece(charContent : XML.ArrayChars);
  2231. VAR i, j, m, tpos : LONGINT; ch, last : Char32; tempUCS32 : ARRAY 1024 OF Char32;
  2232. oldpos, len : LONGINT; tstr : ARRAY 10 OF CHAR;
  2233. sr : Streams.StringReader;
  2234. lengthCounter : LONGINT;
  2235. string : Strings.String;
  2236. BEGIN
  2237. KernelLog.String("INSERT PIECE!!!!");
  2238. m := LEN(tempUCS32) - 1;
  2239. NEW(sr, charContent.GetLength());
  2240. string := charContent.GetStr();
  2241. IF (charContent.GetLength()<1) THEN RETURN END;
  2242. sr.SetRaw(string^, 0, charContent.GetLength());
  2243. (* Files.OpenReader(r, charContent.GetFile(), charContent.GetPos()); *)
  2244. oldpos := text.GetLength();
  2245. len := charContent.GetLength();
  2246. KernelLog.String("StartPos : "); KernelLog.Int(charContent.GetPos(), 5); KernelLog.String(" len : ");
  2247. KernelLog.Int(charContent.GetLength(), 5); KernelLog.Ln;
  2248. tpos := 0; lengthCounter := 0;
  2249. REPEAT
  2250. IF GetUTF8Char(sr, ch, tpos) THEN
  2251. IF ch = ORD("&") THEN
  2252. j := 0; tstr[j] := "&";
  2253. REPEAT
  2254. INC(j);
  2255. IF GetUTF8Char(sr, ch, tpos) THEN tstr[j] := CHR(ch) END
  2256. UNTIL (j >= LEN(tstr)-2) OR (tstr[j] = ";");
  2257. tstr[j+1] := 0X;
  2258. IF tstr ="&amp;" THEN ch := ORD("&")
  2259. ELSIF tstr ="&lt;" THEN ch := ORD("<")
  2260. ELSIF tstr ="&gt;" THEN ch := ORD(">")
  2261. ELSIF tstr ="&rbrk;" THEN ch := ORD("]")
  2262. END;
  2263. END;
  2264. IF i = m THEN tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32); i := 0 END;
  2265. IF (last # ORD(CR)) OR (ch # ORD(LF)) THEN
  2266. IF ch = ORD(CR) THEN tempUCS32[i] := ORD(LF)
  2267. ELSE tempUCS32[i] := ch
  2268. END;
  2269. INC(i)
  2270. END;
  2271. last := ch;
  2272. INC(lengthCounter);
  2273. END
  2274. UNTIL (tpos >= len) OR (sr.res # Streams.Ok);
  2275. tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32);
  2276. IF pstyle # NIL THEN text.SetParagraphStyle(oldpos, len, pstyle); END;
  2277. IF cstyle # NIL THEN
  2278. (* KernelLog.String("Setting Style: "); KernelLog.String(cstyle.name); KernelLog.Ln; *)
  2279. text.SetCharacterStyle(oldpos, lengthCounter, cstyle);
  2280. NEW(attr); attr.color := cstyle.color;
  2281. attr.bgcolor := cstyle.bgColor;
  2282. NEW(fonti); COPY(cstyle.family, fonti.name);
  2283. fonti.size := ENTIER(DTPUtilities.FixpToFloat(cstyle.size));
  2284. fonti.style := cstyle.style;
  2285. attr.fontInfo := fonti;
  2286. (* text.SetAttributes(oldpos, len, attr); *)
  2287. ELSIF (cstyle = NIL) & (pstyle # NIL) THEN
  2288. KernelLog.String("empty"); KernelLog.Ln;
  2289. cstyle := pstyle.charStyle;
  2290. text.SetCharacterStyle(oldpos, len, cstyle);
  2291. NEW(attr); attr.color := cstyle.color;
  2292. attr.bgcolor := cstyle.bgColor;
  2293. NEW(fonti); COPY(cstyle.family, fonti.name);
  2294. fonti.size := ENTIER(DTPUtilities.FixpToFloat(cstyle.size));
  2295. fonti.style := cstyle.style;
  2296. attr.fontInfo := fonti;
  2297. (* text.SetAttributes(oldpos, len, attr); *)
  2298. END;
  2299. END InsertPiece;
  2300. PROCEDURE InsertChar(ch : Texts.Char32);
  2301. VAR buf : ARRAY 2 OF Texts.Char32;
  2302. oldpos: LONGINT;
  2303. BEGIN
  2304. oldpos := text.GetLength(); len := 1;
  2305. buf[0] := ch; buf[1] := 0;
  2306. text.InsertUCS32(text.GetLength(), buf); (* cursor moves automagically *)
  2307. IF pstyle # NIL THEN text.SetParagraphStyle(oldpos, len, pstyle); END;
  2308. IF cstyle # NIL THEN
  2309. text.SetCharacterStyle(oldpos, len, cstyle);
  2310. NEW(attr); attr.color := cstyle.color;
  2311. attr.bgcolor := cstyle.bgColor;
  2312. NEW(fonti); COPY(cstyle.family, fonti.name);
  2313. fonti.size := ENTIER(DTPUtilities.FixpToFloat(cstyle.size));
  2314. fonti.style := cstyle.style;
  2315. attr.fontInfo := fonti;
  2316. (* text.SetAttributes(oldpos, len, attr); *)
  2317. ELSIF (cstyle = NIL) & (pstyle # NIL) THEN
  2318. cstyle := pstyle.charStyle;
  2319. text.SetCharacterStyle(oldpos, len, cstyle);
  2320. NEW(attr); attr.color := cstyle.color;
  2321. attr.bgcolor := cstyle.bgColor;
  2322. NEW(fonti); COPY(cstyle.family, fonti.name);
  2323. fonti.size := ENTIER(DTPUtilities.FixpToFloat(cstyle.size));
  2324. fonti.style := cstyle.style;
  2325. attr.fontInfo := fonti;
  2326. (* text.SetAttributes(oldpos, len, attr); *)
  2327. END;
  2328. END InsertChar;
  2329. BEGIN
  2330. NEW(text); len := 0;
  2331. text.AcquireWrite;
  2332. node := elem.GetContents(); node.Reset();
  2333. WHILE node.HasMoreElements() DO
  2334. ptr := node.GetNext();
  2335. IF ptr IS XML.Element THEN
  2336. str := ptr(XML.Element).GetName();
  2337. IF (str # NIL) & (str^ = "node-attribute") THEN (* process node-attributes *)
  2338. str := ptr(XML.Element).GetAttributeValue("name");
  2339. IF (str # NIL) & (str^ = "chain-next") THEN
  2340. str := ptr(XML.Element).GetAttributeValue("value");
  2341. IF (str # NIL) THEN
  2342. COPY(str^, chainNextN);
  2343. END;
  2344. ELSIF (str # NIL) & (str^ = "chain-prev") THEN
  2345. str := ptr(XML.Element).GetAttributeValue("value");
  2346. IF (str # NIL) THEN
  2347. COPY(str^, chainPrevN);
  2348. END
  2349. END;
  2350. ELSIF (str # NIL) & (str^ = "node") THEN (* process paragraphs *)
  2351. str := ptr(XML.Element).GetAttributeValue("name");
  2352. IF (str # NIL) & (str^ = "paragraph") THEN
  2353. para := ptr(XML.Element).GetContents(); para.Reset();
  2354. WHILE para.HasMoreElements() DO
  2355. ptr := para.GetNext();
  2356. IF ptr IS XML.Element THEN
  2357. str := ptr(XML.Element).GetName();
  2358. IF (str # NIL) & (str^ = "node-attribute") THEN (* process paragraph-attributes *)
  2359. str := ptr(XML.Element).GetAttributeValue("name");
  2360. IF (str # NIL) & (str^ = "style") THEN
  2361. str := ptr(XML.Element).GetAttributeValue("value");
  2362. IF (str # NIL) THEN
  2363. pstyle := Texts.GetParagraphStyleByName(str^);
  2364. ELSE
  2365. END;
  2366. END;
  2367. ELSIF (str # NIL) & (str^ = "node") THEN (* process spans *)
  2368. str := ptr(XML.Element).GetAttributeValue("name");
  2369. IF (str # NIL) & (str^ = "span") THEN
  2370. span := ptr(XML.Element).GetContents(); span.Reset();
  2371. WHILE span.HasMoreElements() DO
  2372. ptr := span.GetNext();
  2373. IF ptr IS XML.Element THEN
  2374. str := ptr(XML.Element).GetName();
  2375. IF (str # NIL) & (str^ = "node-attribute") THEN (* process span-attributes *)
  2376. str := ptr(XML.Element).GetAttributeValue("name");
  2377. IF (str # NIL) & (str^ = "style") THEN
  2378. str := ptr(XML.Element).GetAttributeValue("value");
  2379. IF (str # NIL) THEN
  2380. cstyle := Texts.GetCharacterStyleByName(str^);
  2381. (* KernelLog.String("Loading: "); KernelLog.String(cstyle.name); KernelLog.Ln; *)
  2382. ELSE
  2383. IF (pstyle # NIL) THEN
  2384. cstyle := pstyle.charStyle;
  2385. END;
  2386. END;
  2387. END;
  2388. ELSIF (str # NIL) & (str^ = "node") THEN (* process content *)
  2389. str := ptr(XML.Element).GetAttributeValue("name");
  2390. IF (str # NIL) & (str^ = "CDATA") THEN
  2391. tc := ptr(XML.Element).GetContents(); tc.Reset();
  2392. IF tc.HasMoreElements() THEN
  2393. ptr := tc.GetNext();
  2394. IF ptr IS XML.CDataSect THEN
  2395. InsertPiece(ptr(XML.CDataSect));
  2396. END;
  2397. END;
  2398. END;
  2399. ELSE
  2400. END; (* end content *)
  2401. END;
  2402. END;
  2403. ELSIF (str # NIL) & (str^ = "object") THEN (* object char *)
  2404. span := ptr(XML.Element).GetContents(); span.Reset();
  2405. WHILE span.HasMoreElements() DO
  2406. ptr := span.GetNext();
  2407. IF ptr IS XML.Element THEN
  2408. str := ptr(XML.Element).GetName();
  2409. IF (str # NIL) & (str^ = "node-attribute") THEN (* process object-attributes *)
  2410. str := ptr(XML.Element).GetAttributeValue("name");
  2411. IF (str # NIL) & (str^ = "file") THEN
  2412. str := ptr(XML.Element).GetAttributeValue("value");
  2413. IF (str # NIL) THEN
  2414. (* KernelLog.String("loading object piece: "); KernelLog.String(str^); KernelLog.Ln; *)
  2415. NEW(img); done := FALSE;
  2416. (* Raster.Load(img, str^, done); *)
  2417. image := WMGraphics.LoadImage(str^, FALSE);
  2418. IF image # NIL THEN
  2419. img.image := image;
  2420. img.file := str;
  2421. NEW(obj); obj.object := img;
  2422. text.InsertPiece(text.GetLength(), obj);
  2423. END;
  2424. END;
  2425. END;
  2426. END;
  2427. END;
  2428. END;
  2429. END; (* end object *)
  2430. ELSE
  2431. END; (* end spans *)
  2432. END;
  2433. END;
  2434. END;
  2435. IF node.HasMoreElements() THEN
  2436. InsertChar(10);
  2437. END;
  2438. ELSE
  2439. END; (* end paragraphs *)
  2440. END;
  2441. END;
  2442. text.ReleaseWrite;
  2443. SetText(text);
  2444. END Load;
  2445. PROCEDURE FixLinks*;
  2446. VAR obj: DTPData.ContentObject;
  2447. BEGIN
  2448. obj := ownerDoc.GetContentByName(chainNextN);
  2449. IF obj # NIL THEN chainNext := obj(TextObject); END;
  2450. obj := ownerDoc.GetContentByName(chainPrevN);
  2451. IF obj # NIL THEN chainPrev := obj(TextObject); END;
  2452. END FixLinks;
  2453. PROCEDURE Store*(VAR w: Files.Writer);
  2454. VAR tempString: ARRAY 256 OF CHAR;
  2455. cStyle : Texts.CharacterStyle;
  2456. pStyle : Texts.ParagraphStyle;
  2457. ch : Texts.Char32;
  2458. r : Texts.TextReader;
  2459. forceStyle: BOOLEAN;
  2460. PROCEDURE WriteParagraph(pstyle: BOOLEAN);
  2461. BEGIN
  2462. w.String(' <node name="paragraph">'); w.Ln;
  2463. IF pstyle THEN
  2464. w.String(' <node-attribute name="style" value="'); w.String(pStyle.name); w.String('" />'); w.Ln;
  2465. ELSE
  2466. w.String(' <node-attribute name="style" value="defaultParagraphStyle" />'); w.Ln;
  2467. END;
  2468. END WriteParagraph;
  2469. PROCEDURE WriteSpan(cstyle: BOOLEAN);
  2470. BEGIN
  2471. w.String(' <node name="span">'); w.Ln;
  2472. IF cstyle THEN
  2473. w.String(' <node-attribute name="style" value="'); w.String(cStyle.name); w.String('" />'); w.Ln;
  2474. ELSE
  2475. w.String(' <node-attribute name="style" value="defaultCharacterStyle" />'); w.Ln;
  2476. END;
  2477. w.String(' <node name="CDATA"><![CDATA[');
  2478. END WriteSpan;
  2479. BEGIN
  2480. text.AcquireRead;
  2481. NEW(r, text); forceStyle := FALSE;
  2482. w.String(' <node-attribute name="type" value="Text" />'); w.Ln;
  2483. IF chainPrev # NIL THEN COPY(chainPrev.contentName^, tempString); ELSE tempString := "none"; END;
  2484. w.String(' <node-attribute name="chain-prev" value="'); w.String(tempString); w.String('" />'); w.Ln;
  2485. IF chainNext # NIL THEN COPY(chainNext.contentName^, tempString); ELSE tempString := "none"; END;
  2486. w.String(' <node-attribute name="chain-next" value="'); w.String(tempString); w.String('" />'); w.Ln;
  2487. (* w.String(' <node-attribute name="first-pos" value="'); w.String(tempString); w.String('" />'); w.Ln;
  2488. w.String(' <node-attribute name="first-line" value="'); w.String(tempString); w.String('" />'); w.Ln;
  2489. *) r.ReadCh(ch);
  2490. IF chainPrev = NIL THEN
  2491. IF (r.pstyle # NIL) THEN
  2492. pStyle := r.pstyle;
  2493. WriteParagraph(TRUE);
  2494. ELSE
  2495. pStyle := NIL;
  2496. WriteParagraph(FALSE);
  2497. END;
  2498. IF (r.cstyle # NIL) THEN
  2499. cStyle := r.cstyle;
  2500. WriteSpan(TRUE);
  2501. ELSE
  2502. IF (r.pstyle # NIL) THEN
  2503. cStyle := r.pstyle.charStyle;
  2504. ELSE
  2505. cStyle := NIL;
  2506. END;
  2507. WriteSpan(FALSE);
  2508. END;
  2509. (* WriteSection(TRUE, TRUE); *)
  2510. WHILE ~r.eot DO
  2511. IF ch = Texts.ObjectChar THEN
  2512. IF (r.object # NIL) & (r.object IS Image) THEN
  2513. (* KernelLog.String("objectchar found"); KernelLog.Ln; *)
  2514. w.String(']]></node>'); w.Ln; (* close CDATA *)
  2515. w.String(' </node>'); w.Ln; (* close Span *)
  2516. w.String(' <node name="object">'); w.Ln; (* open new Object *)
  2517. w.String(' <node-attribute name="file" value="'); w.String(r.object(Image).file^); w.String('" />'); w.Ln;
  2518. w.String(' </node>'); w.Ln; (* close Object *)
  2519. WriteSpan(FALSE); (* open new Span *)
  2520. END;
  2521. ELSIF ch < 128 THEN
  2522. CASE CHR(ch) OF
  2523. |"<" : w.String("&lt;");
  2524. |">" : w.String("&gt;");
  2525. |"&" : w.String("&amp;");
  2526. |"]" : w.String("&rbrk;");
  2527. ELSE
  2528. IF (ch = 10) THEN
  2529. w.String(']]></node>'); w.Ln;
  2530. w.String(' </node>'); w.Ln;
  2531. w.String(' </node>'); w.Ln;
  2532. forceStyle := TRUE;
  2533. ELSE
  2534. TextUtilities.WriteUTF8Char(w, ch);
  2535. END;
  2536. END;
  2537. ELSE TextUtilities.WriteUTF8Char(w, ch);
  2538. END;
  2539. r.ReadCh(ch);
  2540. IF (forceStyle) THEN (* newline, open new paragraph & span *)
  2541. IF (r.pstyle # NIL) THEN
  2542. pStyle := r.pstyle;
  2543. WriteParagraph(TRUE);
  2544. ELSE
  2545. pStyle := NIL;
  2546. WriteParagraph(FALSE);
  2547. END;
  2548. IF (r.cstyle # NIL) THEN
  2549. cStyle := r.cstyle;
  2550. WriteSpan(TRUE);
  2551. ELSE
  2552. IF (r.pstyle # NIL) THEN
  2553. cStyle := r.pstyle.charStyle;
  2554. WriteSpan(TRUE);
  2555. ELSE
  2556. cStyle := NIL;
  2557. WriteSpan(FALSE);
  2558. END;
  2559. END;
  2560. forceStyle := FALSE;
  2561. ELSIF (cStyle = NIL) & (r.cstyle # NIL)THEN
  2562. w.String(']]></node>'); w.Ln;
  2563. w.String(' </node>'); w.Ln;
  2564. cStyle := r.cstyle;
  2565. WriteSpan(TRUE);
  2566. ELSIF (cStyle # NIL) & (r.cstyle = NIL) THEN
  2567. w.String(']]></node>'); w.Ln;
  2568. w.String(' </node>'); w.Ln;
  2569. IF (pStyle # NIL) THEN
  2570. cStyle := pStyle.charStyle;
  2571. WriteSpan(TRUE);
  2572. ELSE
  2573. cStyle := NIL;
  2574. WriteSpan(FALSE);
  2575. END;
  2576. ELSIF (cStyle # NIL) & (r.cstyle # NIL) & (cStyle.name # r.cstyle.name) THEN
  2577. w.String(']]></node>'); w.Ln;
  2578. w.String(' </node>'); w.Ln;
  2579. cStyle := r.cstyle;
  2580. WriteSpan(TRUE);
  2581. END;
  2582. END;
  2583. w.String(']]></node>'); w.Ln;
  2584. w.String(' </node>'); w.Ln;
  2585. w.String(' </node>'); w.Ln;
  2586. END;
  2587. text.ReleaseRead;
  2588. END Store;
  2589. PROCEDURE Show*(x, y: LONGINT);
  2590. BEGIN
  2591. props.Show(x, y);
  2592. END Show;
  2593. PROCEDURE Hide*;
  2594. VAR viewport: WMWindowManager.ViewPort;
  2595. BEGIN
  2596. viewport := WMWindowManager.GetDefaultView();
  2597. UpdatePosition(props.bounds.l-ENTIER(viewport.range.l), props.bounds.t-ENTIER(viewport.range.t));
  2598. props.Hide;
  2599. END Hide;
  2600. PROCEDURE Close*;
  2601. BEGIN
  2602. Hide;
  2603. END Close;
  2604. END TextObject;
  2605. TextPropWindow = OBJECT(WMComponents.FormWindow)
  2606. VAR theCaller : TextObject;
  2607. shown: BOOLEAN;
  2608. chain, vAlign: WMEditors.Editor;
  2609. pList, cList, gList, customList : WMStringGrids.StringGrid;
  2610. insert: WMStandardComponents.Button;
  2611. PROCEDURE &New*(caller: TextObject);
  2612. VAR vc: WMComponents.VisualComponent;
  2613. BEGIN
  2614. theCaller := caller;
  2615. manager := WMWindowManager.GetDefaultManager();
  2616. vc := CreatePropertyForm();
  2617. Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), TRUE);
  2618. SetContent(vc);
  2619. SetTitle(Strings.NewString("Content"));
  2620. shown := FALSE;
  2621. END New;
  2622. PROCEDURE CreatePropertyForm(): WMComponents.VisualComponent;
  2623. VAR panel, panel2, panel3: WMStandardComponents.Panel;
  2624. resizerV: WMStandardComponents.Resizer;
  2625. label: WMStandardComponents.Label;
  2626. windowStyle : WMWindowManager.WindowStyle;
  2627. labelWidth: LONGINT; panelColor : WMGraphics.Color;
  2628. BEGIN
  2629. labelWidth := 90;
  2630. windowStyle := manager.GetStyle();
  2631. panelColor := windowStyle.bgColor;
  2632. NEW(panel); panel.bounds.SetExtents(190 , 350); panel.fillColor.Set(panelColor);
  2633. panel.takesFocus.Set(TRUE);
  2634. NEW(panel2); panel2.bounds.SetHeight(20); panel2.alignment.Set(WMComponents.AlignTop);
  2635. panel.AddContent(panel2);
  2636. NEW(label); label.alignment.Set(WMComponents.AlignLeft); label.SetCaption(" Chain next:");
  2637. panel2.AddContent(label); label.bounds.SetWidth(labelWidth); label.textColor.Set(0000000FFH);
  2638. NEW(chain); chain.alignment.Set(WMComponents.AlignClient);
  2639. chain.tv.showBorder.Set(TRUE); chain.multiLine.Set(FALSE); chain.fillColor.Set(0FFFFFFFFH);
  2640. chain.tv.textAlignV.Set(WMGraphics.AlignCenter);
  2641. chain.onEnter.Add(SetValueHandler); chain.tv.borders.Set(WMRectangles.MakeRect(3,3,1,1));
  2642. chain.SetAsString("none");
  2643. panel2.AddContent(chain);
  2644. NEW(panel2); panel2.bounds.SetHeight(20); panel2.alignment.Set(WMComponents.AlignTop);
  2645. (* panel.AddContent(panel2); *)
  2646. NEW(label); label.alignment.Set(WMComponents.AlignLeft); label.SetCaption(" Vertical Align:");
  2647. panel2.AddContent(label); label.bounds.SetWidth(labelWidth); label.textColor.Set(0000000FFH);
  2648. NEW(vAlign); vAlign.alignment.Set(WMComponents.AlignClient);
  2649. vAlign.tv.showBorder.Set(TRUE); vAlign.multiLine.Set(FALSE); vAlign.fillColor.Set(0FFFFFFFFH);
  2650. vAlign.tv.textAlignV.Set(WMGraphics.AlignCenter);
  2651. vAlign.onEnter.Add(SetValueHandler); vAlign.tv.borders.Set(WMRectangles.MakeRect(3,3,1,1));
  2652. vAlign.SetAsString("Top");
  2653. panel2.AddContent(vAlign);
  2654. NEW(panel2); panel2.bounds.SetHeight(20); panel2.alignment.Set(WMComponents.AlignTop);
  2655. panel.AddContent(panel2);
  2656. NEW(label); label.alignment.Set(WMComponents.AlignLeft); label.SetCaption(" Object:");
  2657. panel2.AddContent(label); label.bounds.SetWidth(labelWidth); label.textColor.Set(0000000FFH);
  2658. NEW(insert); insert.alignment.Set(WMComponents.AlignClient); insert.caption.SetAOC("Insert");
  2659. insert.onClick.Add(InsertHandler);
  2660. panel2.AddContent(insert);
  2661. (* style choosers *)
  2662. NEW(panel2); panel2.alignment.Set(WMComponents.AlignClient);
  2663. panel.AddContent(panel2);
  2664. NEW(panel3); panel3.bounds.SetHeight(5); panel3.alignment.Set(WMComponents.AlignTop);
  2665. panel2.AddContent(panel3);
  2666. NEW(panel3); panel3.bounds.SetHeight(150); panel3.alignment.Set(WMComponents.AlignTop); panel3.fillColor.Set(0FFCCCCFFH);
  2667. NEW(label); label.alignment.Set(WMComponents.AlignTop); label.SetCaption(" Paragraph Styles:");
  2668. label.fillColor.Set(panelColor); label.bounds.SetHeight(20); label.textColor.Set(0000000FFH);
  2669. panel3.AddContent(label);
  2670. NEW(pList); pList.alignment.Set(WMComponents.AlignClient);
  2671. pList.onClick.Add(PClickSelected);
  2672. pList.model.Acquire;
  2673. pList.model.SetNofCols(1);
  2674. pList.model.SetNofRows(1);
  2675. pList.SetSelectionMode(WMGrids.GridSelectRows);
  2676. pList.model.Release;
  2677. panel3.AddContent(pList);
  2678. panel2.AddContent(panel3);
  2679. NEW(resizerV); resizerV.alignment.Set(WMComponents.AlignBottom);
  2680. resizerV.bounds.SetHeight(4);
  2681. panel3.AddContent(resizerV);
  2682. NEW(panel3); panel3.alignment.Set(WMComponents.AlignClient); panel3.fillColor.Set(0CCFFCCFFH);
  2683. NEW(label); label.alignment.Set(WMComponents.AlignTop); label.SetCaption(" Character Styles:");
  2684. label.fillColor.Set(panelColor); label.bounds.SetHeight(20); label.textColor.Set(0000000FFH);
  2685. panel3.AddContent(label);
  2686. NEW(cList); cList.alignment.Set(WMComponents.AlignClient);
  2687. cList.onClick.Add(CClickSelected);
  2688. cList.model.Acquire;
  2689. cList.model.SetNofCols(1);
  2690. cList.model.SetNofRows(1);
  2691. cList.SetSelectionMode(WMGrids.GridSelectRows);
  2692. cList.model.Release;
  2693. panel3.AddContent(cList);
  2694. panel2.AddContent(panel3);
  2695. RETURN panel;
  2696. END CreatePropertyForm;
  2697. PROCEDURE Show*(x, y: LONGINT);
  2698. BEGIN
  2699. IF ~shown THEN
  2700. shown := TRUE;
  2701. RefreshValues;
  2702. LoadStyleList;
  2703. WMWindowManager.ExtAddWindow(SELF, x, y,
  2704. {WMWindowManager.FlagFrame, WMWindowManager.FlagStayOnTop, WMWindowManager.FlagClose, WMWindowManager.FlagMinimize});
  2705. END;
  2706. END Show;
  2707. PROCEDURE Hide*;
  2708. BEGIN
  2709. IF shown THEN
  2710. shown := FALSE;
  2711. manager.Remove(SELF);
  2712. END;
  2713. END Hide;
  2714. PROCEDURE RefreshValues;
  2715. VAR content: TextObject;
  2716. tempString: ARRAY 32 OF CHAR;
  2717. BEGIN
  2718. content := theCaller.chainNext;
  2719. IF (content = NIL) THEN tempString := "none"; ELSE COPY(content.contentName^, tempString); END;
  2720. chain.SetAsString(tempString);
  2721. chain.Invalidate;
  2722. IF (theCaller.vAlign = 0) THEN
  2723. tempString := "Top";
  2724. ELSIF (theCaller.vAlign = 1) THEN
  2725. tempString := "Center";
  2726. ELSIF (theCaller.vAlign = 2) THEN
  2727. tempString := "Bottom";
  2728. ELSIF (theCaller.vAlign = 3) THEN
  2729. tempString := "Justified";
  2730. ELSE
  2731. tempString := "Top";
  2732. END;
  2733. vAlign.SetAsString(tempString);
  2734. vAlign.Invalidate;
  2735. END RefreshValues;
  2736. PROCEDURE SetValueHandler(sender, data: ANY);
  2737. VAR content: DTPData.ContentObject;
  2738. fieldValue: ARRAY 32 OF CHAR;
  2739. textObj, nextTextObj: TextObject;
  2740. text : Texts.Text;
  2741. BEGIN
  2742. IF (sender = vAlign) THEN
  2743. vAlign.GetAsString(fieldValue);
  2744. Strings.LowerCase(fieldValue);
  2745. IF (fieldValue = "0") OR (fieldValue = "top") THEN
  2746. theCaller.vAlign := 0; vAlign.SetAsString("Top");
  2747. ELSIF (fieldValue = "1") OR (fieldValue = "center") THEN
  2748. theCaller.vAlign := 1; vAlign.SetAsString("Center");
  2749. ELSIF (fieldValue = "2") OR (fieldValue = "bottom") THEN
  2750. theCaller.vAlign := 2; vAlign.SetAsString("Bottom");
  2751. ELSIF (fieldValue = "3") OR (fieldValue = "justified") THEN
  2752. theCaller.vAlign := 3; vAlign.SetAsString("Justified");
  2753. ELSE
  2754. theCaller.vAlign := 0; vAlign.SetAsString("Top");
  2755. END;
  2756. (* call vAlign changed *)
  2757. ELSIF (sender = chain) THEN
  2758. chain.GetAsString(fieldValue);
  2759. (* KernelLog.String("Chain: "); KernelLog.String(fieldValue); KernelLog.Ln; *)
  2760. (* IF (fieldValue # "none") THEN *)
  2761. content := theCaller.ownerDoc.GetContentByName(fieldValue);
  2762. IF (content # NIL) THEN
  2763. IF (content IS TextObject) THEN
  2764. IF (content.contentName # theCaller.contentName) THEN
  2765. (* remove previous chain first, if any *)
  2766. textObj := theCaller.chainNext;
  2767. WHILE textObj # NIL DO
  2768. nextTextObj := textObj.chainNext;
  2769. textObj.chainPrev := NIL;
  2770. textObj.chainNext := NIL;
  2771. NEW(text); textObj.SetText(text);
  2772. textObj := nextTextObj;
  2773. END;
  2774. (* set the new chain *)
  2775. theCaller.chainNext := content(TextObject);
  2776. content(TextObject).chainPrev := theCaller;
  2777. content(TextObject).SetText(theCaller.text);
  2778. theCaller.Update;
  2779. theCaller.ChainUpdate;
  2780. ELSE
  2781. textObj := theCaller.chainNext;
  2782. WHILE textObj # NIL DO
  2783. nextTextObj := textObj.chainNext;
  2784. textObj.chainPrev := NIL;
  2785. textObj.chainNext := NIL;
  2786. NEW(text); textObj.SetText(text);
  2787. textObj := nextTextObj;
  2788. END;
  2789. theCaller.chainNext := NIL;
  2790. chain.SetAsString("none");
  2791. END;
  2792. ELSE
  2793. textObj := theCaller.chainNext;
  2794. WHILE textObj # NIL DO
  2795. nextTextObj := textObj.chainNext;
  2796. textObj.chainPrev := NIL;
  2797. textObj.chainNext := NIL;
  2798. NEW(text); textObj.SetText(text);
  2799. textObj := nextTextObj;
  2800. END;
  2801. theCaller.chainNext := NIL;
  2802. chain.SetAsString("none");
  2803. END;
  2804. ELSE
  2805. textObj := theCaller.chainNext;
  2806. WHILE textObj # NIL DO
  2807. nextTextObj := textObj.chainNext;
  2808. textObj.chainPrev := NIL;
  2809. textObj.chainNext := NIL;
  2810. NEW(text); textObj.SetText(text);
  2811. textObj := nextTextObj;
  2812. END;
  2813. theCaller.chainNext := NIL;
  2814. chain.SetAsString("none");
  2815. END;
  2816. (* END; *)
  2817. END;
  2818. theCaller.Redraw;
  2819. RefreshValues;
  2820. END SetValueHandler;
  2821. PROCEDURE InsertHandler(sender, data: ANY);
  2822. VAR filename: ARRAY 128 OF CHAR;
  2823. BEGIN
  2824. filename := "star.gif";
  2825. IF WMDialogs.QueryString("Insert Image:", filename) = WMDialogs.ResOk THEN
  2826. InsertImg(filename);
  2827. END;
  2828. END InsertHandler;
  2829. PROCEDURE InsertImg(CONST file: ARRAY OF CHAR);
  2830. VAR done: BOOLEAN;
  2831. img: Image;
  2832. image : WMGraphics.Image;
  2833. obj: Texts.ObjectPiece;
  2834. BEGIN
  2835. NEW(img); NEW(image); done := FALSE;
  2836. (* Raster.Load(img, file, done); *)
  2837. image := WMGraphics.LoadImage(file, FALSE);
  2838. IF image # NIL THEN
  2839. img.image := image;
  2840. img.file := Strings.NewString(file);
  2841. NEW(obj); obj.object := img;
  2842. (* KernelLog.String("inserting piece in text: "); KernelLog.String(file); KernelLog.Ln; *)
  2843. theCaller.text.AcquireWrite;
  2844. theCaller.text.InsertPiece(theCaller.cursor.GetPosition(), obj);
  2845. theCaller.text.ReleaseWrite;
  2846. END;
  2847. END InsertImg;
  2848. PROCEDURE Close*;
  2849. BEGIN
  2850. shown := FALSE;
  2851. Hide;
  2852. Close^;
  2853. END Close;
  2854. PROCEDURE LoadStyleList*;
  2855. VAR i : LONGINT;
  2856. doc : DTPData.Document;
  2857. BEGIN
  2858. doc := theCaller.ownerDoc;
  2859. pList.model.Acquire;
  2860. i := 0;
  2861. WHILE ((i<LEN(doc.pStyles)) & (doc.pStyles[i] # NIL)) DO
  2862. pList.model.SetNofRows(i+1);
  2863. pList.model.SetCellText(0, i, Strings.NewString(doc.pStyles[i].name));
  2864. pList.model.SetCellData(0, i, doc.pStyles[i]);
  2865. INC(i);
  2866. END;
  2867. (* PClickSelected(NIL, pList.model.GetCellData(0, 0)); *)
  2868. pList.model.Release;
  2869. cList.model.Acquire;
  2870. i := 0;
  2871. WHILE ((i<LEN(doc.cStyles)) & (doc.cStyles[i] # NIL)) DO
  2872. cList.model.SetNofRows(i+1);
  2873. cList.model.SetCellText(0, i, Strings.NewString(doc.cStyles[i].name));
  2874. cList.model.SetCellData(0, i, doc.cStyles[i]);
  2875. INC(i);
  2876. END;
  2877. (* CClickSelected(NIL, cList.model.GetCellData(0, 0)); *)
  2878. cList.model.Release;
  2879. END LoadStyleList;
  2880. PROCEDURE PClickSelected(sender, data: ANY);
  2881. VAR text : Texts.Text;
  2882. from, to : Texts.TextPosition;
  2883. utilreader : Texts.TextReader;
  2884. attr : Texts.Attributes;
  2885. currentPStyle : DTPData.ParagraphStyleObject;
  2886. pStyle : Texts.ParagraphStyle;
  2887. cStyle : Texts.CharacterStyle;
  2888. a, b, ch : LONGINT;
  2889. BEGIN
  2890. IF (data # NIL ) THEN
  2891. currentPStyle := data(DTPData.ParagraphStyleObject);
  2892. IF Texts.GetLastSelection(text, from, to) THEN
  2893. (* check if there is a style with that name *)
  2894. pStyle := Texts.GetParagraphStyleByName(currentPStyle.name);
  2895. IF (pStyle = NIL) THEN (* create the style & add to list *)
  2896. NEW(pStyle); COPY(currentPStyle.name, pStyle.name);
  2897. Texts.AddParagraphStyle(pStyle);
  2898. END;
  2899. pStyle.alignment := currentPStyle.alignment;
  2900. pStyle.spaceBefore := DTPUtilities.FloatToFixp(currentPStyle.spaceBefore);
  2901. pStyle.spaceAfter := DTPUtilities.FloatToFixp(currentPStyle.spaceAfter);
  2902. pStyle.leftIndent := DTPUtilities.FloatToFixp(currentPStyle.leftIndent);
  2903. pStyle.rightIndent := DTPUtilities.FloatToFixp(currentPStyle.rightIndent);
  2904. pStyle.firstIndent := DTPUtilities.FloatToFixp(currentPStyle.firstIndent);
  2905. NEW(cStyle);
  2906. COPY(currentPStyle.charStyle.name, cStyle.name);
  2907. COPY(currentPStyle.charStyle.family, cStyle.family);
  2908. cStyle.style := currentPStyle.charStyle.style;
  2909. cStyle.size := DTPUtilities.FloatToFixp(currentPStyle.charStyle.size);
  2910. cStyle.leading := DTPUtilities.FloatToFixp(currentPStyle.charStyle.leading);
  2911. cStyle.baselineShift := DTPUtilities.FloatToFixp(currentPStyle.charStyle.baselineShift);
  2912. cStyle.color := currentPStyle.charStyle.color;
  2913. cStyle.bgColor := currentPStyle.charStyle.bgColor;
  2914. cStyle.tracking := DTPUtilities.FloatToFixp(currentPStyle.charStyle.tracking);
  2915. (* cStyle.kerning := currentPStyle.charStyle.kerning; *)
  2916. cStyle.scaleHorizontal := DTPUtilities.FloatToFixp(currentPStyle.charStyle.scaleHorizontal);
  2917. cStyle.scaleVertical := DTPUtilities.FloatToFixp(currentPStyle.charStyle.scaleVertical);
  2918. pStyle.charStyle := cStyle;
  2919. (* prepare attributes *)
  2920. NEW(attr); NEW(attr.fontInfo);
  2921. COPY(currentPStyle.charStyle.family, attr.fontInfo.name);
  2922. attr.fontInfo.size := ENTIER(currentPStyle.charStyle.size);
  2923. attr.fontInfo.style := currentPStyle.charStyle.style;
  2924. attr.color := currentPStyle.charStyle.color;
  2925. attr.fontInfo.fontcache := NIL;
  2926. text.AcquireWrite;
  2927. a := MIN(from.GetPosition(), to.GetPosition());
  2928. b := MAX(from.GetPosition(), to.GetPosition());
  2929. NEW(utilreader, text);
  2930. utilreader.SetPosition(a);
  2931. utilreader.ReadCh(ch);
  2932. text.SetParagraphStyle(a, b - a, pStyle);
  2933. (* set attributes for back compatibility - dont*)
  2934. (* text.SetAttributes(a, b - a, attr); *)
  2935. text.ReleaseWrite;
  2936. theCaller.layout.FullLayout(theCaller.firstPos, theCaller.firstLineI); theCaller.CheckNumberOfLines;
  2937. END;
  2938. END;
  2939. END PClickSelected;
  2940. PROCEDURE CClickSelected(sender, data: ANY);
  2941. VAR text : Texts.Text;
  2942. from, to : Texts.TextPosition;
  2943. utilreader : Texts.TextReader;
  2944. attr : Texts.Attributes;
  2945. currentCStyle : DTPData.CharacterStyleObject;
  2946. cStyle : Texts.CharacterStyle;
  2947. a, b, ch : LONGINT;
  2948. BEGIN
  2949. IF (data # NIL ) THEN
  2950. currentCStyle := data(DTPData.CharacterStyleObject);
  2951. IF Texts.GetLastSelection(text, from, to) THEN
  2952. (* check if there is a style with that name *)
  2953. cStyle := Texts.GetCharacterStyleByName(currentCStyle.name);
  2954. IF (cStyle = NIL) THEN (* create the style & add to list *)
  2955. NEW(cStyle); COPY(currentCStyle.name, cStyle.name);
  2956. Texts.AddCharacterStyle(cStyle);
  2957. END;
  2958. COPY(currentCStyle.family, cStyle.family);
  2959. cStyle.style := currentCStyle.style;
  2960. cStyle.size := DTPUtilities.FloatToFixp(currentCStyle.size);
  2961. cStyle.leading := DTPUtilities.FloatToFixp(currentCStyle.leading);
  2962. cStyle.baselineShift := DTPUtilities.FloatToFixp(currentCStyle.baselineShift);
  2963. cStyle.color := currentCStyle.color;
  2964. cStyle.bgColor := currentCStyle.bgColor;
  2965. cStyle.tracking := DTPUtilities.FloatToFixp(currentCStyle.tracking);
  2966. (* cStyle.kerning := currentCStyle.kerning; *)
  2967. cStyle.scaleHorizontal := DTPUtilities.FloatToFixp(currentCStyle.scaleHorizontal);
  2968. cStyle.scaleVertical := DTPUtilities.FloatToFixp(currentCStyle.scaleVertical);
  2969. (* prepare attributes *)
  2970. NEW(attr); NEW(attr.fontInfo);
  2971. COPY(cStyle.family, attr.fontInfo.name);
  2972. attr.fontInfo.size := ENTIER(DTPUtilities.FixpToFloat(cStyle.size));
  2973. attr.fontInfo.style := cStyle.style;
  2974. attr.color := cStyle.color;
  2975. attr.fontInfo.fontcache := NIL;
  2976. text.AcquireWrite;
  2977. a := MIN(from.GetPosition(), to.GetPosition());
  2978. b := MAX(from.GetPosition(), to.GetPosition());
  2979. NEW(utilreader, text);
  2980. utilreader.SetPosition(a);
  2981. utilreader.ReadCh(ch);
  2982. text.SetCharacterStyle(a, b - a, cStyle);
  2983. (* set attributes for back compatibility *)
  2984. (* text.SetAttributes(a, b - a, attr); *)
  2985. text.ReleaseWrite;
  2986. theCaller.layout.FullLayout(theCaller.firstPos, theCaller.firstLineI); theCaller.CheckNumberOfLines;
  2987. END;
  2988. END;
  2989. END CClickSelected;
  2990. END TextPropWindow;
  2991. (* --------------------------------------------------------------------------- *)
  2992. VAR
  2993. PTVfirstLine : WMProperties.Int32Property;
  2994. PTVborders, PTVbounds : WMProperties.RectangleProperty;
  2995. PROCEDURE GenText*() : DTPData.ContentObject;
  2996. VAR text: TextObject;
  2997. BEGIN
  2998. NEW(text);
  2999. RETURN text;
  3000. END GenText;
  3001. PROCEDURE Register*;
  3002. BEGIN
  3003. DTPEditor.plugRegistry.RegisterPlugin(pluginName, GenText);
  3004. END Register;
  3005. PROCEDURE Cleanup;
  3006. BEGIN
  3007. DTPEditor.plugRegistry.UnregisterPlugin(pluginName);
  3008. END Cleanup;
  3009. PROCEDURE Limit(x, min, max : LONGINT) : LONGINT;
  3010. BEGIN
  3011. IF x < min THEN x := min END;
  3012. IF x > max THEN x := max END;
  3013. RETURN x
  3014. END Limit;
  3015. PROCEDURE TextViewDefaults;
  3016. BEGIN
  3017. NEW(PTVfirstLine, NIL, Strings.NewString("firstLine"),
  3018. Strings.NewString("the first visible line of text in the view"));
  3019. PTVfirstLine.Set(0);
  3020. NEW(PTVborders, NIL, Strings.NewString("borders"),
  3021. Strings.NewString("spaces from bounds of the component to the text"));
  3022. PTVborders.Set(WMRectangles.MakeRect(5, 5, 5, 5));
  3023. NEW(PTVbounds, NIL, Strings.NewString("bounds"),
  3024. Strings.NewString("bounds of the component"));
  3025. PTVbounds.Set(WMRectangles.MakeRect(100, 100, 100, 100));
  3026. END TextViewDefaults;
  3027. BEGIN
  3028. TextViewDefaults;
  3029. Modules.InstallTermHandler(Cleanup);
  3030. END DTPText.
  3031. System.Free DTPText