Changeset 30:1e14cb29290a
- Timestamp:
- 01/27/08 20:37:23
(1 year ago)
- Author:
- Frank Benoit <benoit@tionex.de>
- branch:
- default
- Message:
TextLayout?
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r28 |
r30 |
|
| 94 | 94 | |
|---|
| 95 | 95 | public wchar[] toCharArray( char[] str ){ |
|---|
| 96 | | return StrToWCHARs( str ); |
|---|
| | 96 | return toString16( str ); |
|---|
| 97 | 97 | } |
|---|
| 98 | 98 | |
|---|
| r29 |
r30 |
|
| 32 | 32 | import tango.text.convert.Format; |
|---|
| 33 | 33 | import dwt.dwthelper.utils; |
|---|
| | 34 | import dwt.dwthelper.System; |
|---|
| 34 | 35 | |
|---|
| 35 | 36 | /** |
|---|
| … | … | |
| 65 | 66 | StyleItem[][] runs; |
|---|
| 66 | 67 | int[] lineOffset, lineY, lineWidth; |
|---|
| 67 | | int mLangFontLink2; |
|---|
| | 68 | void* mLangFontLink2; |
|---|
| 68 | 69 | |
|---|
| 69 | 70 | static const wchar LTR_MARK = '\u200E', RTL_MARK = '\u200F'; |
|---|
| … | … | |
| 94 | 95 | /*Place info (malloc when the run is placed) */ |
|---|
| 95 | 96 | int* advances; |
|---|
| 96 | | int* goffsets; |
|---|
| 97 | | int* width; |
|---|
| 98 | | int* ascent; |
|---|
| 99 | | int* descent; |
|---|
| 100 | | int* leading; |
|---|
| 101 | | int* x; |
|---|
| | 97 | GOFFSET* goffsets; |
|---|
| | 98 | int width; |
|---|
| | 99 | int ascent; |
|---|
| | 100 | int descent; |
|---|
| | 101 | int leading; |
|---|
| | 102 | int x; |
|---|
| 102 | 103 | |
|---|
| 103 | 104 | /* Justify info (malloc during computeRuns) */ |
|---|
| … | … | |
| 107 | 108 | SCRIPT_LOGATTR* psla; |
|---|
| 108 | 109 | |
|---|
| 109 | | int* fallbackFont; |
|---|
| | 110 | HFONT fallbackFont; |
|---|
| 110 | 111 | |
|---|
| 111 | 112 | void free() { |
|---|
| … | … | |
| 146 | 147 | } |
|---|
| 147 | 148 | if (fallbackFont !is null) { |
|---|
| 148 | | if (mLangFontLink2 !is 0) { |
|---|
| | 149 | if (mLangFontLink2 !is null) { |
|---|
| 149 | 150 | /* ReleaseFont() */ |
|---|
| 150 | | OS.VtblCall(8, mLangFontLink2, fallbackFont); |
|---|
| | 151 | OS.VtblCall(8, mLangFontLink2, cast(int)fallbackFont); |
|---|
| 151 | 152 | } |
|---|
| 152 | 153 | fallbackFont = null; |
|---|
| 153 | 154 | } |
|---|
| 154 | | width = ascent = descent = x = 0; |
|---|
| | 155 | width = 0; |
|---|
| | 156 | ascent = 0; |
|---|
| | 157 | descent = 0; |
|---|
| | 158 | x = 0; |
|---|
| 155 | 159 | lineBreak = softBreak = false; |
|---|
| 156 | 160 | } |
|---|
| … | … | |
| 185 | 189 | styles[1] = new StyleItem(); |
|---|
| 186 | 190 | text = ""; //$NON-NLS-1$ |
|---|
| 187 | | int[] ppv = new int[1]; |
|---|
| 188 | | OS.OleInitialize(0); |
|---|
| 189 | | if (OS.CoCreateInstance(CLSID_CMultiLanguage, 0, OS.CLSCTX_INPROC_SERVER, IID_IMLangFontLink2, ppv) is OS.S_OK) { |
|---|
| 190 | | mLangFontLink2 = ppv[0]; |
|---|
| | 191 | void* ppv; |
|---|
| | 192 | OS.OleInitialize(null); |
|---|
| | 193 | if (OS.CoCreateInstance(CLSID_CMultiLanguage.ptr, null, OS.CLSCTX_INPROC_SERVER, IID_IMLangFontLink2.ptr, cast(void*)&ppv) is OS.S_OK) { |
|---|
| | 194 | mLangFontLink2 = ppv; |
|---|
| 191 | 195 | } |
|---|
| 192 | 196 | if (device.tracking) device.new_Object(this); |
|---|
| … | … | |
| 194 | 198 | |
|---|
| 195 | 199 | void breakRun(StyleItem run) { |
|---|
| 196 | | if (run.psla !is 0) return; |
|---|
| 197 | | char[] chars = new char[run.length]; |
|---|
| 198 | | segmentsText.getChars(run.start, run.start + run.length, chars, 0); |
|---|
| 199 | | int hHeap = OS.GetProcessHeap(); |
|---|
| 200 | | run.psla = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, SCRIPT_LOGATTR.sizeof * chars.length); |
|---|
| 201 | | if (run.psla is 0) DWT.error(DWT.ERROR_NO_HANDLES); |
|---|
| 202 | | OS.ScriptBreak(chars, chars.length, run.analysis, run.psla); |
|---|
| 203 | | } |
|---|
| 204 | | |
|---|
| 205 | | void checkItem (int hDC, StyleItem item) { |
|---|
| 206 | | if (item.fallbackFont !is 0) { |
|---|
| | 200 | if (run.psla !is null) return; |
|---|
| | 201 | wchar[] chars = StrToWCHARs( segmentsText[ run.start .. run.start + run.length ] ); |
|---|
| | 202 | auto hHeap = OS.GetProcessHeap(); |
|---|
| | 203 | run.psla = cast(SCRIPT_LOGATTR*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, SCRIPT_LOGATTR.sizeof * chars.length); |
|---|
| | 204 | if (run.psla is null) DWT.error(DWT.ERROR_NO_HANDLES); |
|---|
| | 205 | OS.ScriptBreak(chars.ptr, chars.length, &run.analysis, run.psla); |
|---|
| | 206 | } |
|---|
| | 207 | |
|---|
| | 208 | void checkItem (HDC hDC, StyleItem item) { |
|---|
| | 209 | if (item.fallbackFont !is null) { |
|---|
| 207 | 210 | /* |
|---|
| 208 | 211 | * Feature in Windows. The fallback font returned by the MLang service |
|---|
| … | … | |
| 213 | 216 | */ |
|---|
| 214 | 217 | LOGFONT logFont; |
|---|
| 215 | | if (OS.GetObject(item.fallbackFont, LOGFONT.sizeof, &logFont) is 0) { |
|---|
| | 218 | if (OS.GetObject( item.fallbackFont, LOGFONT.sizeof, &logFont) is 0) { |
|---|
| 216 | 219 | item.free(); |
|---|
| 217 | 220 | OS.SelectObject(hDC, getItemFont(item)); |
|---|
| … | … | |
| 231 | 234 | void computeRuns (GC gc) { |
|---|
| 232 | 235 | if (runs !is null) return; |
|---|
| 233 | | int hDC = gc !is null ? gc.handle : device.internal_new_GC(null); |
|---|
| 234 | | int srcHdc = OS.CreateCompatibleDC(hDC); |
|---|
| | 236 | auto hDC = gc !is null ? gc.handle : device.internal_new_GC(null); |
|---|
| | 237 | auto srcHdc = OS.CreateCompatibleDC(hDC); |
|---|
| 235 | 238 | allRuns = itemize(); |
|---|
| 236 | 239 | for (int i=0; i<allRuns.length - 1; i++) { |
|---|
| … | … | |
| 239 | 242 | shape(srcHdc, run); |
|---|
| 240 | 243 | } |
|---|
| 241 | | SCRIPT_LOGATTR logAttr = new SCRIPT_LOGATTR(); |
|---|
| 242 | | SCRIPT_PROPERTIES properties = new SCRIPT_PROPERTIES(); |
|---|
| | 244 | SCRIPT_LOGATTR* logAttr; |
|---|
| | 245 | SCRIPT_PROPERTIES* properties; |
|---|
| 243 | 246 | int lineWidth = indent, lineStart = 0, lineCount = 1; |
|---|
| 244 | 247 | for (int i=0; i<allRuns.length - 1; i++) { |
|---|
| … | … | |
| 289 | 292 | piDx[0] = run.width; |
|---|
| 290 | 293 | } else { |
|---|
| 291 | | OS.ScriptGetLogicalWidths(run.analysis, run.length, run.glyphCount, run.advances, run.clusters, run.visAttrs, piDx); |
|---|
| | 294 | OS.ScriptGetLogicalWidths(&run.analysis, run.length, run.glyphCount, run.advances, run.clusters, run.visAttrs, piDx.ptr); |
|---|
| 292 | 295 | } |
|---|
| 293 | 296 | int width = 0, maxWidth = wrapWidth - lineWidth; |
|---|
| … | … | |
| 300 | 303 | breakRun(run); |
|---|
| 301 | 304 | while (start >= 0) { |
|---|
| 302 | | OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); |
|---|
| | 305 | logAttr = run.psla + start; |
|---|
| | 306 | //OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); |
|---|
| 303 | 307 | if (logAttr.fSoftBreak || logAttr.fWhiteSpace) break; |
|---|
| 304 | 308 | start--; |
|---|
| … | … | |
| 312 | 316 | if (start is 0 && i !is lineStart && !run.tab) { |
|---|
| 313 | 317 | if (logAttr.fSoftBreak && !logAttr.fWhiteSpace) { |
|---|
| 314 | | OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof); |
|---|
| | 318 | properties = device.scripts[run.analysis.eScript]; |
|---|
| | 319 | //OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof); |
|---|
| 315 | 320 | int langID = properties.langid; |
|---|
| 316 | 321 | StyleItem pRun = allRuns[i - 1]; |
|---|
| 317 | | OS.MoveMemory(properties, device.scripts[pRun.analysis.eScript], SCRIPT_PROPERTIES.sizeof); |
|---|
| | 322 | //OS.MoveMemory(properties, device.scripts[pRun.analysis.eScript], SCRIPT_PROPERTIES.sizeof); |
|---|
| 318 | 323 | if (properties.langid is langID || langID is OS.LANG_NEUTRAL || properties.langid is OS.LANG_NEUTRAL) { |
|---|
| 319 | 324 | breakRun(pRun); |
|---|
| 320 | | OS.MoveMemory(logAttr, pRun.psla + ((pRun.length - 1) * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); |
|---|
| | 325 | logAttr = pRun.psla + (pRun.length - 1); |
|---|
| | 326 | //OS.MoveMemory(logAttr, pRun.psla + ((pRun.length - 1) * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); |
|---|
| 321 | 327 | if (!logAttr.fWhiteSpace) start = -1; |
|---|
| 322 | 328 | } |
|---|
| … | … | |
| 336 | 342 | breakRun(run); |
|---|
| 337 | 343 | while (start < run.length) { |
|---|
| 338 | | OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); |
|---|
| | 344 | logAttr = run.psla + start; |
|---|
| | 345 | //OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); |
|---|
| 339 | 346 | if (!logAttr.fWhiteSpace) break; |
|---|
| 340 | 347 | start++; |
|---|
| … | … | |
| 370 | 377 | } |
|---|
| 371 | 378 | lineWidth = 0; |
|---|
| 372 | | runs = new StyleItem[lineCount][]; |
|---|
| | 379 | runs = new StyleItem[][](lineCount); |
|---|
| 373 | 380 | lineOffset = new int[lineCount + 1]; |
|---|
| 374 | 381 | lineY = new int[lineCount + 1]; |
|---|
| … | … | |
| 408 | 415 | } |
|---|
| 409 | 416 | } |
|---|
| 410 | | int hHeap = OS.GetProcessHeap(); |
|---|
| | 417 | auto hHeap = OS.GetProcessHeap(); |
|---|
| 411 | 418 | int newLineWidth = 0; |
|---|
| 412 | 419 | for (int j = 0; j < runs[line].length; j++) { |
|---|
| … | … | |
| 414 | 421 | int iDx = item.width * wrapWidth / lineWidth; |
|---|
| 415 | 422 | if (iDx !is item.width) { |
|---|
| 416 | | item.justify = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, item.glyphCount * 4); |
|---|
| 417 | | if (item.justify is 0) DWT.error(DWT.ERROR_NO_HANDLES); |
|---|
| | 423 | item.justify = cast(int*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, item.glyphCount * 4); |
|---|
| | 424 | if (item.justify is null) DWT.error(DWT.ERROR_NO_HANDLES); |
|---|
| 418 | 425 | OS.ScriptJustify(item.visAttrs, item.advances, item.glyphCount, iDx - item.width, 2, item.justify); |
|---|
| 419 | 426 | item.width = iDx; |
|---|
| … | … | |
| 447 | 454 | } |
|---|
| 448 | 455 | } |
|---|
| 449 | | if (srcHdc !is 0) OS.DeleteDC(srcHdc); |
|---|
| | 456 | if (srcHdc !is null) OS.DeleteDC(srcHdc); |
|---|
| 450 | 457 | if (gc is null) device.internal_dispose_GC(hDC, null); |
|---|
| 451 | 458 | } |
|---|
| … | … | |
| 467 | 474 | lineY = null; |
|---|
| 468 | 475 | lineWidth = null; |
|---|
| 469 | | if (mLangFontLink2 !is 0) { |
|---|
| | 476 | if (mLangFontLink2 !is null) { |
|---|
| 470 | 477 | /* Release() */ |
|---|
| 471 | 478 | OS.VtblCall(2, mLangFontLink2); |
|---|
| 472 | | mLangFontLink2 = 0; |
|---|
| | 479 | mLangFontLink2 = null; |
|---|
| 473 | 480 | } |
|---|
| 474 | 481 | OS.OleUninitialize(); |
|---|
| … | … | |
| 553 | 560 | if (selectionForeground !is null && selectionForeground.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
|---|
| 554 | 561 | if (selectionBackground !is null && selectionBackground.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
|---|
| 555 | | int length = text.length(); |
|---|
| | 562 | int length = text.length; |
|---|
| 556 | 563 | if (length is 0 && flags is 0) return; |
|---|
| 557 | | int hdc = gc.handle; |
|---|
| | 564 | auto hdc = gc.handle; |
|---|
| 558 | 565 | Rectangle clip = gc.getClipping(); |
|---|
| 559 | 566 | GCData data = gc.data; |
|---|
| 560 | | int gdipGraphics = data.gdipGraphics; |
|---|
| 561 | | int foreground = data.foreground; |
|---|
| 562 | | int alpha = data.alpha; |
|---|
| 563 | | bool gdip = gdipGraphics !is 0 && (alpha !is 0xFF || data.foregroundPattern !is null); |
|---|
| 564 | | int clipRgn = 0; |
|---|
| | 567 | auto gdipGraphics = data.gdipGraphics; |
|---|
| | 568 | auto foreground = data.foreground; |
|---|
| | 569 | auto alpha = data.alpha; |
|---|
| | 570 | bool gdip = gdipGraphics !is null && (alpha !is 0xFF || data.foregroundPattern !is null); |
|---|
| | 571 | HRGN clipRgn; |
|---|
| 565 | 572 | float[] lpXform = null; |
|---|
| 566 | | Rect gdipRect = new Rect(); |
|---|
| 567 | | if (gdipGraphics !is 0 && !gdip) { |
|---|
| 568 | | int matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0); |
|---|
| 569 | | if (matrix is 0) DWT.error(DWT.ERROR_NO_HANDLES); |
|---|
| | 573 | Gdip.Rect gdipRect; |
|---|
| | 574 | if (gdipGraphics !is null && !gdip) { |
|---|
| | 575 | auto matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0); |
|---|
| | 576 | if (matrix is null) DWT.error(DWT.ERROR_NO_HANDLES); |
|---|
| 570 | 577 | Gdip.Graphics_GetTransform(gdipGraphics, matrix); |
|---|
| 571 | | int identity = gc.identity(); |
|---|
| 572 | | Gdip.Matrix_Invert(identity); |
|---|
| 573 | | Gdip.Matrix_Multiply(matrix, identity, Gdip.MatrixOrderAppend); |
|---|
| 574 | | Gdip.Matrix_delete(identity); |
|---|
| | 578 | auto identity_ = gc.identity(); |
|---|
| | 579 | Gdip.Matrix_Invert(identity_); |
|---|
| | 580 | Gdip.Matrix_Multiply(matrix, identity_, Gdip.MatrixOrderAppend); |
|---|
| | 581 | Gdip.Matrix_delete(identity_); |
|---|
| 575 | 582 | if (!Gdip.Matrix_IsIdentity(matrix)) { |
|---|
| 576 | 583 | lpXform = new float[6]; |
|---|
| 577 | | Gdip.Matrix_GetElements(matrix, lpXform); |
|---|
| | 584 | Gdip.Matrix_GetElements(matrix, lpXform.ptr); |
|---|
| 578 | 585 | } |
|---|
| 579 | 586 | Gdip.Matrix_delete(matrix); |
|---|
| … | … | |
| 583 | 590 | } else { |
|---|
| 584 | 591 | Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone); |
|---|
| 585 | | int rgn = Gdip.Region_new(); |
|---|
| | 592 | auto rgn = Gdip.Region_new(); |
|---|
| 586 | 593 | Gdip.Graphics_GetClip(gdipGraphics, rgn); |
|---|
| 587 | 594 | if (!Gdip.Region_IsInfinite(rgn, gdipGraphics)) { |
|---|
| … | … | |
| 593 | 600 | } |
|---|
| 594 | 601 | } |
|---|
| 595 | | int foregroundBrush = 0, state = 0; |
|---|
| | 602 | Gdip.Brush* foregroundBrush; |
|---|
| | 603 | int state = 0; |
|---|
| 596 | 604 | if (gdip) { |
|---|
| 597 | 605 | gc.checkGC(GC.FOREGROUND); |
|---|
| … | … | |
| 604 | 612 | if (lpXform !is null) { |
|---|
| 605 | 613 | OS.SetGraphicsMode(hdc, OS.GM_ADVANCED); |
|---|
| 606 | | OS.SetWorldTransform(hdc, lpXform); |
|---|
| 607 | | } |
|---|
| 608 | | if (clipRgn !is 0) { |
|---|
| | 614 | OS.SetWorldTransform(hdc, cast(XFORM*)lpXform.ptr); |
|---|
| | 615 | } |
|---|
| | 616 | if (clipRgn !is null) { |
|---|
| 609 | 617 | OS.SelectClipRgn(hdc, clipRgn); |
|---|
| 610 | 618 | OS.DeleteObject(clipRgn); |
|---|
| … | … | |
| 620 | 628 | selectionEnd = translateOffset(selectionEnd); |
|---|
| 621 | 629 | } |
|---|
| 622 | | RECT rect = new RECT(); |
|---|
| 623 | | int selBrush = 0, selPen = 0, selBrushFg = 0; |
|---|
| | 630 | RECT rect; |
|---|
| | 631 | void* selBrush; |
|---|
| | 632 | void* selPen; |
|---|
| | 633 | void* selBrushFg; |
|---|
| | 634 | |
|---|
| 624 | 635 | if (hasSelection || (flags & DWT.LAST_LINE_SELECTION) !is 0) { |
|---|
| 625 | 636 | if (gdip) { |
|---|
| 626 | | int bg = selectionBackground.handle; |
|---|
| 627 | | int argb = ((alpha & 0xFF) << 24) | ((bg >> 16) & 0xFF) | (bg & 0xFF00) | ((bg & 0xFF) << 16); |
|---|
| 628 | | int color = Gdip.Color_new(argb); |
|---|
| | 637 | auto bg = selectionBackground.handle; |
|---|
| | 638 | auto argb = ((alpha & 0xFF) << 24) | ((bg >> 16) & 0xFF) | (bg & 0xFF00) | ((bg & 0xFF) << 16); |
|---|
| | 639 | auto color = Gdip.Color_new(argb); |
|---|
| 629 | 640 | selBrush = Gdip.SolidBrush_new(color); |
|---|
| 630 | 641 | Gdip.Color_delete(color); |
|---|
| 631 | | int fg = selectionForeground.handle; |
|---|
| | 642 | auto fg = selectionForeground.handle; |
|---|
| 632 | 643 | argb = ((alpha & 0xFF) << 24) | ((fg >> 16) & 0xFF) | (fg & 0xFF00) | ((fg & 0xFF) << 16); |
|---|
| 633 | 644 | color = Gdip.Color_new(argb); |
|---|
| 634 | 645 | selBrushFg = Gdip.SolidBrush_new(color); |
|---|
| 635 | | selPen = Gdip.Pen_new(selBrushFg, 1); |
|---|
| | 646 | selPen = Gdip.Pen_new( cast(Gdip.Brush*)selBrushFg, 1); |
|---|
| 636 | 647 | Gdip.Color_delete(color); |
|---|
| 637 | 648 | } else { |
|---|
| … | … | |
| 670 | 681 | } |
|---|
| 671 | 682 | if (gdip) { |
|---|
| 672 | | Gdip.Graphics_FillRectangle(gdipGraphics, selBrush, drawX + lineWidth[line], drawY, width, lineHeight - lineSpacing); |
|---|
| | 683 | Gdip.Graphics_FillRectangle(gdipGraphics, cast(Gdip.Brush*)selBrush, drawX + lineWidth[line], drawY, width, lineHeight - lineSpacing); |
|---|
| 673 | 684 | } else { |
|---|
| 674 | 685 | OS.SelectObject(hdc, selBrush); |
|---|
| … | … | |
| 694 | 705 | if (fullSelection) { |
|---|
| 695 | 706 | if (gdip) { |
|---|
| 696 | | Gdip.Graphics_FillRectangle(gdipGraphics, selBrush, drawX, drawY, run.width, lineHeight - lineSpacing); |
|---|
| | 707 | Gdip.Graphics_FillRectangle(gdipGraphics, cast(Gdip.Brush*)selBrush, drawX, drawY, run.width, lineHeight - lineSpacing); |
|---|
| 697 | 708 | } else { |
|---|
| 698 | 709 | OS.SelectObject(hdc, selBrush); |
|---|
| … | … | |
| 701 | 712 | } else { |
|---|
| 702 | 713 | if (run.style !is null && run.style.background !is null) { |
|---|
| 703 | | int bg = run.style.background.handle; |
|---|
| | 714 | auto bg = run.style.background.handle; |
|---|
| 704 | 715 | int drawRunY = drawY + (baseline - run.ascent); |
|---|
| 705 | 716 | if (gdip) { |
|---|
| 706 | 717 | int argb = ((alpha & 0xFF) << 24) | ((bg >> 16) & 0xFF) | (bg & 0xFF00) | ((bg & 0xFF) << 16); |
|---|
| 707 | | int color = Gdip.Color_new(argb); |
|---|
| 708 | | int brush = Gdip.SolidBrush_new(color); |
|---|
| 709 | | Gdip.Graphics_FillRectangle(gdipGraphics, brush, drawX, drawRunY, run.width, run.ascent + run.descent); |
|---|
| | 718 | auto color = Gdip.Color_new(argb); |
|---|
| | 719 | auto brush = Gdip.SolidBrush_new(color); |
|---|
| | 720 | Gdip.Graphics_FillRectangle(gdipGraphics, cast(Gdip.Brush*)brush, drawX, drawRunY, run.width, run.ascent + run.descent); |
|---|
| 710 | 721 | Gdip.Color_delete(color); |
|---|
| 711 | 722 | Gdip.SolidBrush_delete(brush); |
|---|
| 712 | 723 | } else { |
|---|
| 713 | | int hBrush = OS.CreateSolidBrush (bg); |
|---|
| 714 | | int oldBrush = OS.SelectObject(hdc, hBrush); |
|---|
| | 724 | auto hBrush = OS.CreateSolidBrush (bg); |
|---|
| | 725 | auto oldBrush = OS.SelectObject(hdc, hBrush); |
|---|
| 715 | 726 | OS.PatBlt(hdc, drawX, drawRunY, run.width, run.ascent + run.descent, OS.PATCOPY); |
|---|
| 716 | 727 | OS.SelectObject(hdc, oldBrush); |
|---|
| … | … | |
| 724 | 735 | int cChars = run.length; |
|---|
| 725 | 736 | int gGlyphs = run.glyphCount; |
|---|
| 726 | | int[] piX = new int[1]; |
|---|
| 727 | | int advances = run.justify !is 0 ? run.justify : run.advances; |
|---|
| 728 | | OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); |
|---|
| 729 | | int runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX[0] : piX[0]; |
|---|
| | 737 | int piX; |
|---|
| | 738 | int* advances = run.justify !is null ? run.justify : run.advances; |
|---|
| | 739 | OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX); |
|---|
| | 740 | int runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX : piX; |
|---|
| 730 | 741 | rect.left = drawX + runX; |
|---|
| 731 | 742 | rect.top = drawY; |
|---|
| 732 | | OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); |
|---|
| 733 | | runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX[0] : piX[0]; |
|---|
| | 743 | OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX); |
|---|
| | 744 | runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX : piX; |
|---|
| 734 | 745 | rect.right = drawX + runX; |
|---|
| 735 | 746 | rect.bottom = drawY + lineHeight - lineSpacing; |
|---|
| 736 | 747 | if (gdip) { |
|---|
| 737 | | Gdip.Graphics_FillRectangle(gdipGraphics, selBrush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); |
|---|
| | 748 | Gdip.Graphics_FillRectangle(gdipGraphics, cast(Gdip.Brush*)selBrush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); |
|---|
| 738 | 749 | } else { |
|---|
| 739 | 750 | OS.SelectObject(hdc, selBrush); |
|---|
| … | … | |
| 764 | 775 | int cChars = run.length; |
|---|
| 765 | 776 | int gGlyphs = run.glyphCount; |
|---|
| 766 | | int[] piX = new int[1]; |
|---|
| 767 | | int advances = run.justify !is 0 ? run.justify : run.advances; |
|---|
| 768 | | OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); |
|---|
| 769 | | int runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX[0] : piX[0]; |
|---|
| | 777 | int piX; |
|---|
| | 778 | int* advances = run.justify !is null ? run.justify : run.advances; |
|---|
| | 779 | OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX); |
|---|
| | 780 | int runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX : piX; |
|---|
| 770 | 781 | rect.left = drawX + runX; |
|---|
| 771 | 782 | rect.top = drawY; |
|---|
| 772 | | OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); |
|---|
| 773 | | runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX[0] : piX[0]; |
|---|
| | 783 | OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX); |
|---|
| | 784 | runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX : piX; |
|---|
| 774 | 785 | rect.right = drawX + runX; |
|---|
| 775 | 786 | rect.bottom = drawY + lineHeight; |
|---|
| … | … | |
| 777 | 788 | if (gdip) { |
|---|
| 778 | 789 | OS.BeginPath(hdc); |
|---|
| 779 | | OS.ScriptTextOut(hdc, run.psc, drawX, drawRunY, 0, null, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets); |
|---|
| | 790 | OS.ScriptTextOut(hdc, run.psc, drawX, drawRunY, 0, null, &run.analysis , null, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets); |
|---|
| 780 | 791 | OS.EndPath(hdc); |
|---|
| 781 | 792 | int count = OS.GetPath(hdc, null, null, 0); |
|---|
| 782 | 793 | int[] points = new int[count*2]; |
|---|
| 783 | | byte[] types = new byte[count]; |
|---|
| 784 | | OS.GetPath(hdc, points, types, count); |
|---|
| | 794 | ubyte[] types = new ubyte[count]; |
|---|
| | 795 | OS.GetPath(hdc, cast(POINT*)points.ptr, types.ptr, count); |
|---|
| 785 | 796 | for (int typeIndex = 0; typeIndex < types.length; typeIndex++) { |
|---|
| 786 | 797 | int newType = 0; |
|---|
| … | … | |
| 794 | 805 | types[typeIndex] = cast(byte)newType; |
|---|
| 795 | 806 | } |
|---|
| 796 | | int path = Gdip.GraphicsPath_new(points, types, count, Gdip.FillModeAlternate); |
|---|
| 797 | | if (path is 0) DWT.error(DWT.ERROR_NO_HANDLES); |
|---|
| 798 | | int brush = foregroundBrush; |
|---|
| | 807 | auto path = Gdip.GraphicsPath_new(cast(Gdip.Point*)points.ptr, cast(byte*)types.ptr, count, Gdip.FillModeAlternate); |
|---|
| | 808 | if (path is null) DWT.error(DWT.ERROR_NO_HANDLES); |
|---|
| | 809 | auto brush = foregroundBrush; |
|---|
| 799 | 810 | if (fullSelection) { |
|---|
| 800 | | brush = selBrushFg; |
|---|
| | 811 | brush = cast(Gdip.Brush*)selBrushFg; |
|---|
| 801 | 812 | } else { |
|---|
| 802 | 813 | if (run.style !is null && run.style.foreground !is null) { |
|---|
| 803 | | int fg = run.style.foreground.handle; |
|---|
| | 814 | auto fg = run.style.foreground.handle; |
|---|
| 804 | 815 | int argb = ((alpha & 0xFF) << 24) | ((fg >> 16) & 0xFF) | (fg & 0xFF00) | ((fg & 0xFF) << 16); |
|---|
| 805 | | int color = Gdip.Color_new(argb); |
|---|
| 806 | | brush = Gdip.SolidBrush_new(color); |
|---|
| | 816 | auto color = Gdip.Color_new(argb); |
|---|
| | 817 | brush = cast(Gdip.Brush*)Gdip.SolidBrush_new(color); |
|---|
| 807 | 818 | Gdip.Color_delete(color); |
|---|
| 808 | 819 | } |
|---|
| … | … | |
| 815 | 826 | gdipRect.Height = rect.bottom - rect.top; |
|---|
| 816 | 827 | gstate = Gdip.Graphics_Save(gdipGraphics); |
|---|
| 817 | | Gdip.Graphics_SetClip(gdipGraphics, gdipRect, Gdip.CombineModeExclude); |
|---|
| | 828 | Gdip.Graphics_SetClip(gdipGraphics, &gdipRect, Gdip.CombineModeExclude); |
|---|
| 818 | 829 | } |
|---|
| 819 | 830 | int antialias = Gdip.Graphics_GetSmoothingMode(gdipGraphics), textAntialias = 0; |
|---|
| … | … | |
| 840 | 851 | Gdip.Graphics_SetSmoothingMode(gdipGraphics, antialias); |
|---|
| 841 | 852 | if (run.style !is null && (run.style.underline || run.style.strikeout)) { |
|---|
| 842 | | int newPen = hasSelection ? selPen : Gdip.Pen_new(brush, 1); |
|---|
| | 853 | auto newPen = hasSelection ? cast(Gdip.Pen*)selPen : Gdip.Pen_new(brush, 1); |
|---|
| 843 | 854 | Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone); |
|---|
| 844 | 855 | if (run.style.underline) { |
|---|
| … | … | |
| 856 | 867 | Gdip.Graphics_Restore(gdipGraphics, gstate); |
|---|
| 857 | 868 | gstate = Gdip.Graphics_Save(gdipGraphics); |
|---|
| 858 | | Gdip.Graphics_SetClip(gdipGraphics, gdipRect, Gdip.CombineModeIntersect); |
|---|
| | 869 | Gdip.Graphics_SetClip(gdipGraphics, &gdipRect, Gdip.CombineModeIntersect); |
|---|
| 859 | 870 | Gdip.Graphics_SetSmoothingMode(gdipGraphics, textAntialias); |
|---|
| 860 | | Gdip.Graphics_FillPath(gdipGraphics, selBrushFg, path); |
|---|
| | 871 | Gdip.Graphics_FillPath(gdipGraphics, cast(Gdip.Brush*)selBrushFg, path); |
|---|
| 861 | 872 | Gdip.Graphics_SetSmoothingMode(gdipGraphics, antialias); |
|---|
| 862 | 873 | if (run.style !is null && (run.style.underline || run.style.strikeout)) { |
|---|
| … | … | |
| 864 | 875 | if (run.style.underline) { |
|---|
| 865 | 876 | int underlineY = drawY + baseline + 1 - run.style.rise; |
|---|
| 866 | | Gdip.Graphics_DrawLine(gdipGraphics, selPen, rect.left, underlineY, rect.right, underlineY); |
|---|
| | 877 | Gdip.Graphics_DrawLine(gdipGraphics, cast(Gdip.Pen*)selPen, rect.left, underlineY, rect.right, underlineY); |
|---|
| 867 | 878 | } |
|---|
| 868 | 879 | if (run.style.strikeout) { |
|---|
| 869 | 880 | int strikeoutY = drawRunY + run.leading + (run.ascent - run.style.rise) / 2; |
|---|
| 870 | | Gdip.Graphics_DrawLine(gdipGraphics, selPen, rect.left, strikeoutY, rect.right, strikeoutY); |
|---|
| | 881 | Gdip.Graphics_DrawLine(gdipGraphics, cast(Gdip.Pen*)selPen, rect.left, strikeoutY, rect.right, strikeoutY); |
|---|
| 871 | 882 | } |
|---|
| 872 | 883 | Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeHalf); |
|---|
| … | … | |
| 875 | 886 | } |
|---|
| 876 | 887 | Gdip.GraphicsPath_delete(path); |
|---|
| 877 | | if (brush !is selBrushFg && brush !is foregroundBrush) Gdip.SolidBrush_delete(brush); |
|---|
| | 888 | if (brush !is selBrushFg && brush !is foregroundBrush) Gdip.SolidBrush_delete(cast(Gdip.SolidBrush*)brush); |
|---|
| 878 | 889 | } else { |
|---|
| 879 | 890 | int fg = foreground; |
|---|
| … | … | |
| 884 | 895 | } |
|---|
| 885 | 896 | OS.SetTextColor(hdc, fg); |
|---|
| 886 | | OS.ScriptTextOut(hdc, run.psc, drawX + offset, drawRunY, 0, null, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets); |
|---|
| | 897 | OS.ScriptTextOut(hdc, run.psc, drawX + offset, drawRunY, 0, null, &run.analysis , null, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets); |
|---|
| 887 | 898 | if (run.style !is null && (run.style.underline || run.style.strikeout)) { |
|---|
| 888 | | int newPen = hasSelection && fg is selectionForeground.handle ? selPen : OS.CreatePen(OS.PS_SOLID, 1, fg); |
|---|
| 889 | | int oldPen = OS.SelectObject(hdc, newPen); |
|---|
| | 899 | auto newPen = hasSelection && fg is selectionForeground.handle ? cast(HPEN)selPen : OS.CreatePen(OS.PS_SOLID, 1, fg); |
|---|
| | 900 | auto oldPen = OS.SelectObject(hdc, newPen); |
|---|
| 890 | 901 | if (run.style.underline) { |
|---|
| 891 | 902 | int underlineY = drawY + baseline + 1 - run.style.rise; |
|---|
| 892 | | OS.MoveToEx(hdc, drawX, underlineY, 0); |
|---|
| | 903 | OS.MoveToEx(hdc, drawX, underlineY, null); |
|---|
| 893 | 904 | OS.LineTo(hdc, drawX + run.width, underlineY); |
|---|
| 894 | 905 | } |
|---|
| 895 | 906 | if (run.style.strikeout) { |
|---|
| 896 | 907 | int strikeoutY = drawRunY + run.leading + (run.ascent - run.style.rise) / 2; |
|---|
| 897 | | OS.MoveToEx(hdc, drawX, strikeoutY, 0); |
|---|
| | 908 | OS.MoveToEx(hdc, drawX, strikeoutY, null); |
|---|
| 898 | 909 | OS.LineTo(hdc, drawX + run.width, strikeoutY); |
|---|
| 899 | 910 | } |
|---|
| … | … | |
| 903 | 914 | if (partialSelection && fg !is selectionForeground.handle) { |
|---|
| 904 | 915 | OS.SetTextColor(hdc, selectionForeground.handle); |
|---|
| 905 | | OS.ScriptTextOut(hdc, run.psc, drawX + offset, drawRunY, OS.ETO_CLIPPED, rect, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets); |
|---|
| | 916 | OS.ScriptTextOut(hdc, run.psc, drawX + offset, drawRunY, OS.ETO_CLIPPED, &rect, &run.analysis , null, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets); |
|---|
| 906 | 917 | if (run.style !is null && (run.style.underline || run.style.strikeout)) { |
|---|
| 907 | | int oldPen = OS.SelectObject(hdc, selPen); |
|---|
| | 918 | auto oldPen = OS.SelectObject(hdc, selPen); |
|---|
| 908 | 919 | if (run.style.underline) { |
|---|
| 909 | 920 | int underlineY = drawY + baseline + 1 - run.style.rise; |
|---|
| 910 | | OS.MoveToEx(hdc, rect.left, underlineY, 0); |
|---|
| | 921 | OS.MoveToEx(hdc, rect.left, underlineY, null); |
|---|
| 911 | 922 | OS.LineTo(hdc, rect.right, underlineY); |
|---|
| 912 | 923 | } |
|---|
| 913 | 924 | if (run.style.strikeout) { |
|---|
| 914 | 925 | int strikeoutY = drawRunY + run.leading + (run.ascent - run.style.rise) / 2; |
|---|
| 915 | | OS.MoveToEx(hdc, rect.left, strikeoutY, 0); |
|---|
| | 926 | OS.MoveToEx(hdc, rect.left, strikeoutY, null); |
|---|
| 916 | 927 | OS.LineTo(hdc, rect.right, strikeoutY); |
|---|
| 917 | 928 | } |
|---|
| … | … | |
| 926 | 937 | } |
|---|
| 927 | 938 | if (gdip) { |
|---|
| 928 | | if (selBrush !is 0) Gdip.SolidBrush_delete(selBrush); |
|---|
| 929 | | if (selBrushFg !is 0) Gdip.SolidBrush_delete(selBrushFg); |
|---|
| 930 | | if (selPen !is 0) Gdip.Pen_delete(selPen); |
|---|
| | 939 | if (selBrush !is null) Gdip.SolidBrush_delete(cast(Gdip.SolidBrush*)selBrush); |
|---|
| | 940 | if (selBrushFg !is null) Gdip.SolidBrush_delete(cast(Gdip.SolidBrush*)selBrushFg); |
|---|
| | 941 | if (selPen !is null) Gdip.Pen_delete(cast(Gdip.Pen*)selPen); |
|---|
| 931 | 942 | } else { |
|---|
| 932 | 943 | OS.RestoreDC(hdc, state); |
|---|
| 933 | | if (gdipGraphics !is 0) Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc); |
|---|
| 934 | | if (selBrush !is 0) OS.DeleteObject (selBrush); |
|---|
| 935 | | if (selPen !is 0) OS.DeleteObject (selPen); |
|---|
| | 944 | if (gdipGraphics !is null) Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc); |
|---|
| | 945 | if (selBrush !is null) OS.DeleteObject (selBrush); |
|---|
| | 946 | if (selPen !is null) OS.DeleteObject (selPen); |
|---|
| 936 | 947 | } |
|---|
| 937 | 948 | } |
|---|
| … | … | |
| 1023 | 1034 | checkLayout(); |
|---|
| 1024 | 1035 | computeRuns(null); |
|---|
| 1025 | | int length = text.length(); |
|---|
| | 1036 | int length = text.length; |
|---|
| 1026 | 1037 | if (length is 0) return new Rectangle(0, 0, 0, 0); |
|---|
| 1027 | 1038 | if (start > end) return new Rectangle(0, 0, 0, 0); |
|---|
| … | … | |
| 1046 | 1057 | cx = metrics.width * (start - run.start); |
|---|
| 1047 | 1058 | } else if (!run.tab) { |
|---|
| 1048 | | int[] piX = new int[1]; |
|---|
| 1049 | | int advances = run.justify !is 0 ? run.justify : run.advances; |
|---|
| 1050 | | OS.ScriptCPtoX(start - run.start, false, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, run.analysis, piX); |
|---|
| 1051 | | cx = isRTL ? run.width - piX[0] : piX[0]; |
|---|
| | 1059 | int piX; |
|---|
| | 1060 | int* advances = run.justify !is null ? run.justify : run.advances; |
|---|
| | 1061 | OS.ScriptCPtoX(start - run.start, false, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, &run.analysis, &piX); |
|---|
| | 1062 | cx = isRTL ? run.width - piX : piX; |
|---|
| 1052 | 1063 | } |
|---|
| 1053 | 1064 | if (run.analysis.fRTL ^ isRTL) { |
|---|
| … | … | |
| 1063 | 1074 | cx = metrics.width * (end - run.start + 1); |
|---|
| 1064 | 1075 | } else if (!run.tab) { |
|---|
| 1065 | | int[] piX = new int[1]; |
|---|
| 1066 | | int advances = run.justify !is 0 ? run.justify : run.advances; |
|---|
| 1067 | | OS.ScriptCPtoX(end - run.start, true, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, run.analysis, piX); |
|---|
| 1068 | | cx = isRTL ? run.width - piX[0] : piX[0]; |
|---|
| | 1076 | int piX; |
|---|
| | 1077 | int* advances = run.justify !is null ? run.justify : run.advances; |
|---|
| | 1078 | OS.ScriptCPtoX(end - run.start, true, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, &run.analysis, &piX); |
|---|
| | 1079 | cx = isRTL ? run.width - piX : piX; |
|---|
| 1069 | 1080 | } |
|---|
| 1070 | 1081 | if (run.analysis.fRTL ^ isRTL) { |
|---|
| … | … | |
| 1152 | 1163 | } |
|---|
| 1153 | 1164 | |
|---|
| 1154 | | int getItemFont (StyleItem item) { |
|---|
| 1155 | | if (item.fallbackFont !is 0) return item.fallbackFont; |
|---|
| | 1165 | HFONT getItemFont (StyleItem item) { |
|---|
| | 1166 | if (item.fallbackFont !is null) return cast(HFONT) item.fallbackFont; |
|---|
| 1156 | 1167 | if (item.style !is null && item.style.font !is null) { |
|---|
| 1157 | 1168 | return item.style.font.handle; |
|---|
| … | … | |
| 1180 | 1191 | checkLayout(); |
|---|
| 1181 | 1192 | computeRuns(null); |
|---|
| 1182 | | int length = text.length(); |
|---|
| | 1193 | int length = text.length; |
|---|
| 1183 | 1194 | if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE); |
|---|
| 1184 | 1195 | offset = translateOffset(offset); |
|---|
| … | … | |
| 1278 | 1289 | checkLayout(); |
|---|
| 1279 | 1290 | computeRuns(null); |
|---|
| 1280 | | int length = text.length(); |
|---|
| | 1291 | int length = text.length; |
|---|
| 1281 | 1292 | if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE); |
|---|
| 1282 | 1293 | offset = translateOffset(offset); |
|---|
| … | … | |
| 1306 | 1317 | computeRuns(null); |
|---|
| 1307 | 1318 | if (!(0 <= lineIndex && lineIndex < runs.length)) DWT.error(DWT.ERROR_INVALID_RANGE); |
|---|
| 1308 | | int hDC = device.internal_new_GC(null); |
|---|
| 1309 | | int srcHdc = OS.CreateCompatibleDC(hDC); |
|---|
| | 1319 | auto hDC = device.internal_new_GC(null); |
|---|
| | 1320 | auto srcHdc = OS.CreateCompatibleDC(hDC); |
|---|
| 1310 | 1321 | TEXTMETRIC lptm; |
|---|
| 1311 | 1322 | OS.SelectObject(srcHdc, font !is null ? font.handle : device.systemFont); |
|---|
| … | … | |
| 1317 | 1328 | int descent = Math.max(lptm.tmDescent, this.descent); |
|---|
| 1318 | 1329 | int leading = lptm.tmInternalLeading; |
|---|
| 1319 | | if (text.length() !is 0) { |
|---|
| | 1330 | if (text.length !is 0) { |
|---|
| 1320 | 1331 | StyleItem[] lineRuns = runs[lineIndex]; |
|---|
| 1321 | 1332 | for (int i = 0; i<lineRuns.length; i++) { |
|---|
| … | … | |
| 1333 | 1344 | lptm.tmInternalLeading = leading; |
|---|
| 1334 | 1345 | lptm.tmAveCharWidth = 0; |
|---|
| 1335 | | return FontMetrics.win32_new(lptm); |
|---|
| | 1346 | return FontMetrics.win32_new(&lptm); |
|---|
| 1336 | 1347 | } |
|---|
| 1337 | 1348 | |
|---|
| … | … | |
| 1376 | 1387 | checkLayout(); |
|---|
| 1377 | 1388 | computeRuns(null); |
|---|
| 1378 | | int length = text.length(); |
|---|
| | 1389 | int length = text.length; |
|---|
| 1379 | 1390 | if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE); |
|---|
| 1380 | | length = segmentsText.length(); |
|---|
| | 1391 | length = segmentsText.length; |
|---|
| 1381 | 1392 | offset = translateOffset(offset); |
|---|
| 1382 | 1393 | int line; |
|---|
| … | … | |
| 1406 | 1417 | int cChars = run.length; |
|---|
| 1407 | 1418 | int gGlyphs = run.glyphCount; |
|---|
| 1408 | | int[] piX = new int[1]; |
|---|
| 1409 | | int advances = run.justify !is 0 ? run.justify : run.advances; |
|---|
| 1410 | | OS.ScriptCPtoX(runOffset, trailing, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); |
|---|
| | 1419 | int piX; |
|---|
| | 1420 | int* advances = run.justify !is null ? run.justify : run.advances; |
|---|
| | 1421 | OS.ScriptCPtoX(runOffset, trailing, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX); |
|---|
| 1411 | 1422 | if ((orientation & DWT.RIGHT_TO_LEFT) !is 0) { |
|---|
| 1412 | | result = new Point(width + (run.width - piX[0]), lineY[line]); |
|---|
| | 1423 | result = new Point(width + (run.width - piX), lineY[line]); |
|---|
| 1413 | 1424 | } else { |
|---|
| 1414 | | result = new Point(width + piX[0], lineY[line]); |
|---|
| | 1425 | result = new Point(width + piX, lineY[line]); |
|---|
| 1415 | 1426 | } |
|---|
| 1416 | 1427 | } |
|---|
| … | … | |
| 1451 | 1462 | int _getOffset(int offset, int movement, bool forward) { |
|---|
| 1452 | 1463 | computeRuns(null); |
|---|
| 1453 | | int length = text.length(); |
|---|
| | 1464 | int length = text.length; |
|---|
| 1454 | 1465 | if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE); |
|---|
| 1455 | 1466 | if (forward && offset is length) return length; |
|---|
| … | … | |
| 1457 | 1468 | int step = forward ? 1 : -1; |
|---|
| 1458 | 1469 | if ((movement & DWT.MOVEMENT_CHAR) !is 0) return offset + step; |
|---|
| 1459 | | length = segmentsText.length(); |
|---|
| | 1470 | length = segmentsText.length; |
|---|
| 1460 | 1471 | offset = translateOffset(offset); |
|---|
| 1461 | | SCRIPT_LOGATTR logAttr = new SCRIPT_LOGATTR(); |
|---|
| 1462 | | SCRIPT_PROPERTIES properties = new SCRIPT_PROPERTIES(); |
|---|
| | 1472 | SCRIPT_LOGATTR* logAttr; |
|---|
| | 1473 | SCRIPT_PROPERTIES* properties; |
|---|
| 1463 | 1474 | int i = forward ? 0 : allRuns.length - 1; |
|---|
| 1464 | 1475 | offset = validadeOffset(offset, step); |
|---|
| … | … | |
| 1468 | 1479 | if (run.lineBreak && !run.softBreak) return untranslateOffset(run.start); |
|---|
| 1469 | 1480 | if (run.tab) return untranslateOffset(run.start); |
|---|
| 1470 | | OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof); |
|---|
| | 1481 | properties = device.scripts[run.analysis.eScript]; |
|---|
| 1471 | 1482 | bool isComplex = properties.fNeedsCaretInfo || properties.fNeedsWordBreaking; |
|---|
| 1472 | 1483 | if (isComplex) breakRun(run); |
|---|
| 1473 | 1484 | while (run.start <= offset && offset < run.start + run.length) { |
|---|
| 1474 | 1485 | if (isComplex) { |
|---|
| 1475 | | OS.MoveMemory(logAttr, run.psla + ((offset - run.start) * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); |
|---|
| | 1486 | logAttr = run.psla + (offset - run.start); |
|---|
| 1476 | 1487 | } |
|---|
| 1477 | 1488 | switch (movement) { |
|---|
| … | … | |
| 1517 | 1528 | i += step; |
|---|
| 1518 | 1529 | } while (0 <= i && i < allRuns.length - 1 && 0 <= offset && offset < length); |
|---|
| 1519 | | return forward ? text.length() : 0; |
|---|
| | 1530 | return forward ? text.length : 0; |
|---|
| 1520 | 1531 | } |
|---|
| 1521 | 1532 | |
|---|
| … | … | |
| 1607 | 1618 | int cChars = run.length; |
|---|
| 1608 | 1619 | int cGlyphs = run.glyphCount; |
|---|
| 1609 | | int[] piCP = new int[1]; |
|---|
| 1610 | | int[] piTrailing = new int[1]; |
|---|
| | 1620 | int piCP; |
|---|
| | 1621 | int piTrailing; |
|---|
| 1611 | 1622 | if ((orientation & DWT.RIGHT_TO_LEFT) !is 0) { |
|---|
| 1612 | 1623 | xRun = run.width - xRun; |
|---|
| 1613 | 1624 | } |
|---|
| 1614 | | int advances = run.justify !is 0 ? run.justify : run.advances; |
|---|
| 1615 | | OS.ScriptXtoCP(xRun, cChars, cGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piCP, piTrailing); |
|---|
| 1616 | | if (trailing !is null) trailing[0] = piTrailing[0]; |
|---|
| 1617 | | return untranslateOffset(run.start + piCP[0]); |
|---|
| | 1625 | int* advances = run.justify !is null ? run.justify : run.advances; |
|---|
| | 1626 | OS.ScriptXtoCP(xRun, cChars, cGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piCP, &piTrailing); |
|---|
| | 1627 | if (trailing !is null) trailing[0] = piTrailing; |
|---|
| | 1628 | return untranslateOffset(run.start + piCP); |
|---|
| 1618 | 1629 | } |
|---|
| 1619 | 1630 | width += run.width; |
|---|
| … | … | |
| 1711 | 1722 | int nSegments = segments.length; |
|---|
| 1712 | 1723 | if (nSegments <= 1) return text; |
|---|
| 1713 | | int length = text.length(); |
|---|
| | 1724 | int length = text.length; |
|---|
| 1714 | 1725 | if (length is 0) return text; |
|---|
| 1715 | 1726 | if (nSegments is 2) { |
|---|
| … | … | |
| 1720 | 1731 | char[] newChars = new char[length + nSegments]; |
|---|
| 1721 | 1732 | int charCount = 0, segmentCount = 0; |
|---|
| 1722 | | char separator = orientation is DWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK; |
|---|
| | 1733 | wchar separator = orientation is DWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK; |
|---|
| 1723 | 1734 | while (charCount < length) { |
|---|
| 1724 | 1735 | if (segmentCount < nSegments && charCount is segments[segmentCount]) { |
|---|
| … | … | |
| 1732 | 1743 | newChars[charCount + segmentCount++] = separator; |
|---|
| 1733 | 1744 | } |
|---|
| 1734 | | return new char[](newChars, 0, Math.min(charCount + segmentCount, newChars.length)); |
|---|
| | 1745 | return newChars[ 0 .. Math.min(charCount + segmentCount, newChars.length)].dup; |
|---|
| 1735 | 1746 | } |
|---|
| 1736 | 1747 | |
|---|
| … | … | |
| 1764 | 1775 | public TextStyle getStyle (int offset) { |
|---|
| 1765 | 1776 | checkLayout(); |
|---|
| 1766 | | int length = text.length(); |
|---|
| | 1777 | int length = text.length; |
|---|
| 1767 | 1778 | if (!(0 <= offset && offset < length)) DWT.error(DWT.ERROR_INVALID_RANGE); |
|---|
| 1768 | 1779 | for (int i=1; i<styles.length; i++) { |
|---|
| &helli |