⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bidiutil.java

📁 源码为Eclipse开源开发平台桌面开发工具SWT的源代码,
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html *  * Contributors: *     IBM Corporation - initial API and implementation *******************************************************************************/package org.eclipse.swt.internal;import java.util.Hashtable;import org.eclipse.swt.SWT;import org.eclipse.swt.graphics.GC;import org.eclipse.swt.internal.win32.*;/* * Wraps Win32 API used to bidi enable the StyledText widget. */public class BidiUtil {	// Keyboard language ids	public static final int KEYBOARD_NON_BIDI = 0;	public static final int KEYBOARD_BIDI = 1;	// bidi flag	static int isBidiPlatform = -1;	// getRenderInfo flag values	public static final int CLASSIN = 1;	public static final int LINKBEFORE = 2;	public static final int LINKAFTER = 4;	// variables used for providing a listener mechanism for keyboard language 	// switching 	static Hashtable languageMap = new Hashtable ();	static Hashtable keyMap = new Hashtable ();	static Hashtable oldProcMap = new Hashtable ();	/*	 * This code is intentionally commented.  In order	 * to support CLDC, .class cannot be used because	 * it does not compile on some Java compilers when	 * they are targeted for CLDC.	 */	//	static Callback callback = new Callback (BidiUtil.class, "windowProc", 4);	static final String CLASS_NAME = "org.eclipse.swt.internal.BidiUtil";	static Callback callback;	static {		try {			callback = new Callback (Class.forName (CLASS_NAME), "windowProc", 4);		} catch (ClassNotFoundException e) {}	}	// GetCharacterPlacement constants	static final int GCP_REORDER = 0x0002;	static final int GCP_GLYPHSHAPE = 0x0010;	static final int GCP_LIGATE = 0x0020;	static final int GCP_CLASSIN = 0x00080000;	static final byte GCPCLASS_ARABIC = 2;	static final byte GCPCLASS_HEBREW = 2;		static final byte GCPCLASS_LOCALNUMBER = 4;	static final byte GCPCLASS_LATINNUMBER = 5;	static final int GCPGLYPH_LINKBEFORE = 0x8000;	static final int GCPGLYPH_LINKAFTER = 0x4000;	// ExtTextOut constants	static final int ETO_CLIPPED = 0x4;	static final int ETO_GLYPH_INDEX = 0x0010;	// Windows primary language identifiers	static final int LANG_ARABIC = 0x01;	static final int LANG_HEBREW = 0x0d;	// code page identifiers	static final String CD_PG_HEBREW = "1255";	static final String CD_PG_ARABIC = "1256";	// ActivateKeyboard constants	static final int HKL_NEXT = 1;	static final int HKL_PREV = 0;	/*	 * Public character class constants are the same as Windows 	 * platform constants. 	 * Saves conversion of class array in getRenderInfo to arbitrary 	 * constants for now.	 */	public static final int CLASS_HEBREW = GCPCLASS_ARABIC;	public static final int CLASS_ARABIC = GCPCLASS_HEBREW;	public static final int CLASS_LOCALNUMBER = GCPCLASS_LOCALNUMBER;	public static final int CLASS_LATINNUMBER = GCPCLASS_LATINNUMBER;	public static final int REORDER = GCP_REORDER;					public static final int LIGATE = GCP_LIGATE;	public static final int GLYPHSHAPE = GCP_GLYPHSHAPE;/** * Adds a language listener. The listener will get notified when the language of * the keyboard changes (via Alt-Shift on Win platforms).  Do this by creating a  * window proc for the Control so that the window messages for the Control can be * monitored. * <p> * * @param hwnd the handle of the Control that is listening for keyboard language  *  changes * @param runnable the code that should be executed when a keyboard language change *  occurs */public static void addLanguageListener (int hwnd, Runnable runnable) {	languageMap.put(new Integer(hwnd), runnable);	subclass(hwnd);}/** * Proc used for OS.EnumSystemLanguageGroups call during isBidiPlatform test. */static int EnumSystemLanguageGroupsProc(int lpLangGrpId, int lpLangGrpIdString, int lpLangGrpName, int options, int lParam) {	if (lpLangGrpId == OS.LGRPID_HEBREW) {		isBidiPlatform = 1;		return 0;	}	if (lpLangGrpId == OS.LGRPID_ARABIC) {		isBidiPlatform = 1;		return 0;	}	return 1;} /** * Wraps the ExtTextOut function. * <p> * * @param gc the gc to use for rendering * @param renderBuffer the glyphs to render as an array of characters * @param renderDx the width of each glyph in renderBuffer * @param x x position to start rendering * @param y y position to start rendering */public static void drawGlyphs(GC gc, char[] renderBuffer, int[] renderDx, int x, int y) {	int length = renderDx.length;		if (!OS.IsWinCE && (OS.WIN32_MAJOR << 16 | OS.WIN32_MINOR) >= (4 << 16 | 10)) {		if (OS.GetLayout (gc.handle) != 0) {			reverse(renderDx);			renderDx[length-1]--;               //fixes bug 40006			reverse(renderBuffer);		}	}		// render transparently to avoid overlapping segments. fixes bug 40006	int oldBkMode = OS.SetBkMode(gc.handle, OS.TRANSPARENT);	OS.ExtTextOutW(gc.handle, x, y, ETO_GLYPH_INDEX , null, renderBuffer, renderBuffer.length, renderDx);	OS.SetBkMode(gc.handle, oldBkMode);}/** * Return ordering and rendering information for the given text.  Wraps the GetFontLanguageInfo * and GetCharacterPlacement functions. * <p> *  * @param gc the GC to use for measuring of this line, input parameter * @param text text that bidi data should be calculated for, input parameter * @param order an array of integers representing the visual position of each character in *  the text array, output parameter * @param classBuffer an array of integers representing the type (e.g., ARABIC, HEBREW,  *  LOCALNUMBER) of each character in the text array, input/output parameter * @param dx an array of integers representing the pixel width of each glyph in the returned *  glyph buffer, output paramteter * @param flags an integer representing rendering flag information, input parameter * @param offsets text segments that should be measured and reordered separately, input  *  parameter. See org.eclipse.swt.custom.BidiSegmentEvent for details. * @return buffer with the glyphs that should be rendered for the given text */public static char[] getRenderInfo(GC gc, String text, int[] order, byte[] classBuffer, int[] dx, int flags, int [] offsets) {	int fontLanguageInfo = OS.GetFontLanguageInfo(gc.handle);	int hHeap = OS.GetProcessHeap();	int[] lpCs = new int[8];	int cs = OS.GetTextCharset(gc.handle);	boolean isRightOriented = false;	if (!OS.IsWinCE && (OS.WIN32_MAJOR << 16 | OS.WIN32_MINOR) >= (4 << 16 | 10)) {		isRightOriented = OS.GetLayout(gc.handle) != 0;	} 	OS.TranslateCharsetInfo(cs, lpCs, OS.TCI_SRCCHARSET);	TCHAR textBuffer = new TCHAR(lpCs[1], text, false);	int byteCount = textBuffer.length();	boolean linkBefore = (flags & LINKBEFORE) == LINKBEFORE;	boolean linkAfter = (flags & LINKAFTER) == LINKAFTER;	GCP_RESULTS result = new GCP_RESULTS();	result.lStructSize = GCP_RESULTS.sizeof;	result.nGlyphs = byteCount;	int lpOrder = result.lpOrder = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount * 4);	int lpDx = result.lpDx = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount * 4);	int lpClass = result.lpClass = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount);	int lpGlyphs = result.lpGlyphs = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount * 2);	// set required dwFlags	int dwFlags = 0;	int glyphFlags = 0;	// Always reorder.  We assume that if we are calling this function we're	// on a platform that supports bidi.  Fixes 20690.	dwFlags |= GCP_REORDER;	if ((fontLanguageInfo & GCP_LIGATE) == GCP_LIGATE) {		dwFlags |= GCP_LIGATE;		glyphFlags |= 0;	}	if ((fontLanguageInfo & GCP_GLYPHSHAPE) == GCP_GLYPHSHAPE) {		dwFlags |= GCP_GLYPHSHAPE;		if (linkBefore) {			glyphFlags |= GCPGLYPH_LINKBEFORE;		}		if (linkAfter) {			glyphFlags |= GCPGLYPH_LINKAFTER;		}	}	byte[] lpGlyphs2;	if (linkBefore || linkAfter) {		lpGlyphs2 = new byte[2];		lpGlyphs2[0]=(byte)glyphFlags;		lpGlyphs2[1]=(byte)(glyphFlags >> 8);	}	else {		lpGlyphs2 = new byte[] {(byte) glyphFlags};	}	OS.MoveMemory(result.lpGlyphs, lpGlyphs2, lpGlyphs2.length);	if ((flags & CLASSIN) == CLASSIN) {		// set classification values for the substring		dwFlags |= GCP_CLASSIN;		OS.MoveMemory(result.lpClass, classBuffer, classBuffer.length);	}	char[] glyphBuffer = new char[result.nGlyphs];	int glyphCount = 0;	for (int i=0; i<offsets.length-1; i++) {		int offset = offsets [i];		int length = offsets [i+1] - offsets [i];		// The number of glyphs expected is <= length (segment length);		// the actual number returned may be less in case of Arabic ligatures.		result.nGlyphs = length;		TCHAR textBuffer2 = new TCHAR(lpCs[1], text.substring(offset, offset + length), false);		OS.GetCharacterPlacement(gc.handle, textBuffer2, textBuffer2.length(), 0, result, dwFlags);		if (dx != null) {			int [] dx2 = new int [result.nGlyphs];			OS.MoveMemory(dx2, result.lpDx, dx2.length * 4);			if (isRightOriented) { 				reverse(dx2);			} 			System.arraycopy (dx2, 0, dx, glyphCount, dx2.length);		}		if (order != null) {			int [] order2 = new int [length];			OS.MoveMemory(order2, result.lpOrder, order2.length * 4);			translateOrder(order2, glyphCount, isRightOriented);			System.arraycopy (order2, 0, order, offset, length);		}		if (classBuffer != null) {			byte [] classBuffer2 = new byte [length];			OS.MoveMemory(classBuffer2, result.lpClass, classBuffer2.length);			System.arraycopy (classBuffer2, 0, classBuffer, offset, length);		}		char[] glyphBuffer2 = new char[result.nGlyphs];		OS.MoveMemory(glyphBuffer2, result.lpGlyphs, glyphBuffer2.length * 2);		if (isRightOriented) {			reverse(glyphBuffer2);		} 		System.arraycopy (glyphBuffer2, 0, glyphBuffer, glyphCount, glyphBuffer2.length);		glyphCount += glyphBuffer2.length;		// We concatenate successive results of calls to GCP.		// For Arabic, it is the only good method since the number of output		// glyphs might be less than the number of input characters.		// This assumes that the whole line is built by successive adjacent		// segments without overlapping.		result.lpOrder += length * 4;		result.lpDx += length * 4;		result.lpClass += length;		result.lpGlyphs += glyphBuffer2.length * 2;	}	/* Free the memory that was allocated. */	OS.HeapFree(hHeap, 0, lpGlyphs);	OS.HeapFree(hHeap, 0, lpClass);	OS.HeapFree(hHeap, 0, lpDx);	OS.HeapFree(hHeap, 0, lpOrder);	return glyphBuffer;}/** * Return bidi ordering information for the given text.  Does not return rendering  * information (e.g., glyphs, glyph distances).  Use this method when you only need  * ordering information.  Doing so will improve performance.  Wraps the  * GetFontLanguageInfo and GetCharacterPlacement functions. * <p> *  * @param gc the GC to use for measuring of this line, input parameter * @param text text that bidi data should be calculated for, input parameter * @param order an array of integers representing the visual position of each character in *  the text array, output parameter * @param classBuffer an array of integers representing the type (e.g., ARABIC, HEBREW,  *  LOCALNUMBER) of each character in the text array, input/output parameter * @param flags an integer representing rendering flag information, input parameter * @param offsets text segments that should be measured and reordered separately, input  *  parameter. See org.eclipse.swt.custom.BidiSegmentEvent for details. */public static void getOrderInfo(GC gc, String text, int[] order, byte[] classBuffer, int flags, int [] offsets) {	int fontLanguageInfo = OS.GetFontLanguageInfo(gc.handle);	int hHeap = OS.GetProcessHeap();	int[] lpCs = new int[8];	int cs = OS.GetTextCharset(gc.handle);	OS.TranslateCharsetInfo(cs, lpCs, OS.TCI_SRCCHARSET);	TCHAR textBuffer = new TCHAR(lpCs[1], text, false);	int byteCount = textBuffer.length();	boolean isRightOriented = false;	if (!OS.IsWinCE && (OS.WIN32_MAJOR << 16 | OS.WIN32_MINOR) >= (4 << 16 | 10)) {		isRightOriented = OS.GetLayout(gc.handle) != 0;	} 	GCP_RESULTS result = new GCP_RESULTS();	result.lStructSize = GCP_RESULTS.sizeof;	result.nGlyphs = byteCount;	int lpOrder = result.lpOrder = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount * 4);	int lpClass = result.lpClass = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount);	// set required dwFlags, these values will affect how the text gets rendered and	// ordered	int dwFlags = 0;	// Always reorder.  We assume that if we are calling this function we're	// on a platform that supports bidi.  Fixes 20690.	dwFlags |= GCP_REORDER;	if ((fontLanguageInfo & GCP_LIGATE) == GCP_LIGATE) {		dwFlags |= GCP_LIGATE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -