📄 textlayout.java
字号:
* <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> * </ul> */public void draw (GC gc, int x, int y, int selectionStart, int selectionEnd, Color selectionForeground, Color selectionBackground) { checkLayout(); computeRuns(gc); if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); if (selectionForeground != null && selectionForeground.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); if (selectionBackground != null && selectionBackground.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); int length = text.length(); if (length == 0) return; int hdc = gc.handle; boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; if (hasSelection) { selectionStart = Math.min(Math.max(0, selectionStart), length - 1); selectionEnd = Math.min(Math.max(0, selectionEnd), length - 1); if (selectionForeground == null) selectionForeground = device.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); if (selectionBackground == null) selectionBackground = device.getSystemColor(SWT.COLOR_LIST_SELECTION); selectionStart = translateOffset(selectionStart); selectionEnd = translateOffset(selectionEnd); } int foreground = OS.GetTextColor(hdc); int state = OS.SaveDC(hdc); RECT rect = new RECT(); int selBrush = 0; if (hasSelection) selBrush = OS.CreateSolidBrush (selectionBackground.handle); int rop2 = 0; if (OS.IsWinCE) { rop2 = OS.SetROP2(hdc, OS.R2_COPYPEN); OS.SetROP2(hdc, rop2); } else { rop2 = OS.GetROP2(hdc); } int dwRop = rop2 == OS.R2_XORPEN ? OS.PATINVERT : OS.PATCOPY; OS.SetBkMode(hdc, OS.TRANSPARENT); Rectangle clip = gc.getClipping(); for (int line=0; line<runs.length; line++) { int drawX = x, drawY = y + lineY[line]; if (wrapWidth != -1) { switch (alignment) { case SWT.CENTER: drawX += (wrapWidth - lineWidth[line]) / 2; break; case SWT.RIGHT: drawX += wrapWidth - lineWidth[line]; break; } } if (drawX > clip.x + clip.width) continue; if (drawX + lineWidth[line] < clip.x) continue; StyleItem[] lineRuns = runs[line]; int baseline = Math.max(0, this.ascent); for (int i = 0; i < lineRuns.length; i++) { baseline = Math.max(baseline, lineRuns[i].ascent); } int lineHeight = lineY[line+1] - lineY[line]; int alignmentX = drawX; for (int i = 0; i < lineRuns.length; i++) { StyleItem run = lineRuns[i]; if (run.length == 0) continue; if (drawX > clip.x + clip.width) break; if (drawX + run.width >= clip.x) { if (!run.lineBreak || run.softBreak) { int end = run.start + run.length - 1; boolean fullSelection = hasSelection && selectionStart <= run.start && selectionEnd >= end; if (fullSelection) { OS.SelectObject(hdc, selBrush); OS.PatBlt(hdc, drawX, drawY, run.width, lineHeight, dwRop); } else { if (run.style != null && run.style.background != null) { int bg = run.style.background.handle; int drawRunY = drawY + (baseline - run.ascent); int hBrush = OS.CreateSolidBrush (bg); int oldBrush = OS.SelectObject(hdc, hBrush); OS.PatBlt(hdc, drawX, drawRunY, run.width, run.ascent + run.descent, dwRop); OS.SelectObject(hdc, oldBrush); OS.DeleteObject(hBrush); } boolean partialSelection = hasSelection && !(selectionStart > end || run.start > selectionEnd); if (partialSelection) { OS.SelectObject(hdc, selBrush); int selStart = Math.max(selectionStart, run.start) - run.start; int selEnd = Math.min(selectionEnd, end) - run.start; int cChars = run.length; int gGlyphs = run.glyphCount; int[] piX = new int[1]; OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, run.advances, run.analysis, piX); int runX = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? run.width - piX[0] : piX[0]; rect.left = drawX + runX; rect.top = drawY; OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, run.advances, run.analysis, piX); runX = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? run.width - piX[0] : piX[0]; rect.right = drawX + runX; rect.bottom = drawY + lineHeight; OS.PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, dwRop); } } } } drawX += run.width; } drawX = alignmentX; for (int i = 0; i < lineRuns.length; i++) { StyleItem run = lineRuns[i]; if (run.length == 0) continue; if (drawX > clip.x + clip.width) break; if (drawX + run.width >= clip.x) { if (!run.tab && (!run.lineBreak || run.softBreak)) { int end = run.start + run.length - 1; int fg = foreground; boolean fullSelection = hasSelection && selectionStart <= run.start && selectionEnd >= end; if (fullSelection) { fg = selectionForeground.handle; } else { if (run.style != null && run.style.foreground != null) fg = run.style.foreground.handle; } OS.SetTextColor(hdc, fg); OS.SelectObject(hdc, getItemFont(run)); int drawRunY = drawY + (baseline - run.ascent); OS.ScriptTextOut(hdc, run.psc, drawX, drawRunY, 0, null, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, null, run.goffsets); boolean partialSelection = hasSelection && !(selectionStart > end || run.start > selectionEnd); if (!fullSelection && partialSelection && fg != selectionForeground.handle) { OS.SetTextColor(hdc, selectionForeground.handle); int selStart = Math.max(selectionStart, run.start) - run.start; int selEnd = Math.min(selectionEnd, end) - run.start; int cChars = run.length; int gGlyphs = run.glyphCount; int[] piX = new int[1]; OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, run.advances, run.analysis, piX); int runX = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? run.width - piX[0] : piX[0]; rect.left = drawX + runX; rect.top = drawY; OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, run.advances, run.analysis, piX); runX = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? run.width - piX[0] : piX[0]; rect.right = drawX + runX; rect.bottom = drawY + lineHeight; OS.ScriptTextOut(hdc, run.psc, drawX, drawRunY, OS.ETO_CLIPPED, rect, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, null, run.goffsets); } } } drawX += run.width; } } OS.RestoreDC(hdc, state); if (selBrush != 0) OS.DeleteObject (selBrush);}void freeRuns () { if (allRuns == null) return; for (int i=0; i<allRuns.length; i++) { StyleItem run = allRuns[i]; run.free(); } allRuns = null; runs = null; segmentsText = null;}/** * Returns the receiver's horizontal text alignment, which will be one * of <code>SWT.LEFT</code>, <code>SWT.CENTER</code> or * <code>SWT.RIGHT</code>. * * @return the alignment used to positioned text horizontally * * @exception SWTException <ul> * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> * </ul> */public int getAlignment () { checkLayout(); return alignment;}/** * Returns the ascent of the receiver. * * @return the ascent * * @exception SWTException <ul> * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> * </ul> * * @see #getDescent() * @see #setDescent(int) * @see #setAscent(int) * @see #getLineMetrics(int) */public int getAscent () { checkLayout(); return ascent;}/** * Returns the bounds of the receiver. * * @return the bounds of the receiver * * @exception SWTException <ul> * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> * </ul> */public Rectangle getBounds () { checkLayout(); computeRuns(null); int width = 0; if (wrapWidth != -1) { width = wrapWidth; } else { for (int line=0; line<runs.length; line++) { width = Math.max(width, lineWidth[line]); } } return new Rectangle (0, 0, width, lineY[lineY.length - 1]);}/** * Returns the bounds for the specified range of characters. The * bounds is the smallest rectangle that encompasses all characters * in the range. The start and end offsets are inclusive and will be * clamped if out of range. * * @param start the start offset * @param end the end offset * @return the bounds of the character range * * @exception SWTException <ul> * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> * </ul> */public Rectangle getBounds (int start, int end) { checkLayout(); computeRuns(null); int length = text.length(); if (length == 0) return new Rectangle(0, 0, 0, 0); if (start > end) return new Rectangle(0, 0, 0, 0); start = Math.min(Math.max(0, start), length - 1); end = Math.min(Math.max(0, end), length - 1); int startLine = getLineIndex(start); int endLine = getLineIndex(end); length = segmentsText.length(); start = translateOffset(start); end = translateOffset(end); if (startLine != endLine) { int width = 0; int y = lineY[startLine]; while (startLine <= endLine) { width = Math.max (width, lineWidth[startLine++]); } return new Rectangle (0, y, width, lineY[endLine + 1] - y); } int x = 0, startRunX = 0, endRunX = 0, i = 0; StyleItem startRun = null, endRun = null, lastRun; StyleItem[] lineRuns = runs[startLine]; for (; i < lineRuns.length; i++) { StyleItem run = lineRuns[i]; int runEnd = run.start + run.length; if (runEnd == length) runEnd++; if (run.start <= start && start < runEnd) { startRun = run; startRunX = x; break; } x += run.width; } boolean reordered = false; lastRun = startRun; boolean isRTL = (orientation & SWT.RIGHT_TO_LEFT) != 0 ^ (lastRun.analysis.s.uBidiLevel & 1) != 0; for (; i < lineRuns.length; i++) { StyleItem run = lineRuns[i]; if (run != lastRun) { if (isRTL) { reordered = run.start + run.length != lastRun.start; } else { reordered = lastRun.start + lastRun.length != run.start; } } if (reordered) break; lastRun = run; int runEnd = run.start + run.length; if (runEnd == length) runEnd++; if ( run.start <= end && end < runEnd) { endRun = run; endRunX = x; break; } x += run.width; } if (reordered || endRun == null) { int y = lineY[startLine]; return new Rectangle (0, y, lineWidth[startLine], lineY[startLine + 1] - y); } if (((startRun.analysis.s.uBidiLevel & 1) != 0) ^ ((endRun.analysis.s.uBidiLevel & 1) != 0)) { int y = lineY[startLine]; return new Rectangle (startRunX, y, endRunX + endRun.width, lineY[startLine + 1] - y); } int startX, endX; if (startRun.tab) { startX = startRunX; } else { int runOffset = start - startRun.start; int cChars = startRun.length; int gGlyphs = startRun.glyphCount; int[] piX = new int[1]; OS.ScriptCPtoX(runOffset, false, cChars, gGlyphs, startRun.clusters, startRun.visAttrs, startRun.advances, startRun.analysis, piX); if ((orientation & SWT.RIGHT_TO_LEFT) != 0) { piX[0] = startRun.width - piX[0]; } startX = startRunX + piX[0]; } if (endRun.tab) { endX = endRunX + endRun.width; } else { int runOffset = end - endRun.start; int cChars = endRun.length; int gGlyphs = endRun.glyphCount; int[] piX = new int[1]; OS.ScriptCPtoX(runOffset, true, cChars, gGlyphs, endRun.clusters, endRun.visAttrs, endRun.advances, endRun.analysis, piX); if ((orientation & SWT.RIGHT_TO_LEFT) != 0) { piX[0] = endRun.width - piX[0]; } endX = endRunX + piX[0]; } if (startX > endX) { int tmp = startX; startX = endX; endX = tmp; } int width = endX - startX; if (wrapWidth != -1) { switch (alignment) { case SWT.CENTER: startX += (wrapWidth - lineWidth[startLine]) / 2; break; case SWT.RIGHT: startX += wrapWidth - lineWidth[startLine]; break; } } int y = lineY[startLine]; return new Rectangle (startX, y, width, lineY[startLine + 1] - y);}/** * Returns the descent of the receiver. * * @return the descent * * @exception SWTException <ul> * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> * </ul> * * @see #getAscent() * @see #setAscent(int) * @see #setDescent(int) * @see #getLineMetrics(int) */public int getDescent () { checkLayout(); return descent;}/** * Returns the default font currently being used by the receiver * to draw and measure text. * * @return the receiver's font * * @exception SWTException <ul> * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> * </ul> */public Font getFont () { checkLayout(); return font;}int getItemFont(StyleItem item) { if (item.fallbackFont != 0) return item.fallbackFont; if (item.style != null && item.style.font != null) { return item.style.font.handle; } if (this.font != null) { return this.font.handle; } return device.getSystemFont().handle;}/** * Returns the embedding level for the specified character offset. The * embedding level is usually used to determine the directionality of a * character in bidirectional text. * * @param offset the charecter offset * @return the embedding level * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the character offset is out of range</li> * </ul> * @exception SWTException <ul> * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -