📄 basic-win32.c
字号:
/* Pango * basic-win32.c: * * Copyright (C) 1999 Red Hat Software * Copyright (C) 2001 Alexander Larsson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#define BASIC_WIN32_DEBUGGING#include <math.h>#include <stdlib.h>#include <glib.h>#include "pangowin32.h"#include "pango-engine.h"#include "pango-utils.h"#include "basic-common.h"/* No extra fields needed */typedef PangoEngineShape BasicEngineWin32;typedef PangoEngineShapeClass BasicEngineWin32Class ;#define SCRIPT_ENGINE_NAME "BasicScriptEngineWin32"static gboolean pango_win32_debug = FALSE;#ifdef HAVE_USP10_H#include "usp10.h"/* Some languages missing from mingw ("w32api") headers */#ifndef LANG_INVARIANT#define LANG_INVARIANT 0x7f#endif#ifndef LANG_DIVEHI#define LANG_DIVEHI 0x65#endif#ifndef LANG_GALICIAN#define LANG_GALICIAN 0x56#endif#ifndef LANG_KYRGYZ#define LANG_KYRGYZ 0x40#endif#ifndef LANG_MONGOLIAN#define LANG_MONGOLIAN 0x50#endif#ifndef LANG_SYRIAC#define LANG_SYRIAC 0x5a#endifstatic gboolean have_uniscribe = FALSE;static HDC hdc;typedef HRESULT (WINAPI *pScriptGetProperties) (const SCRIPT_PROPERTIES ***, int *);typedef HRESULT (WINAPI *pScriptItemize) (const WCHAR *, int, int, const SCRIPT_CONTROL *, const SCRIPT_STATE *, SCRIPT_ITEM *, int *);typedef HRESULT (WINAPI *pScriptShape) (HDC, SCRIPT_CACHE *, const WCHAR *, int, int, SCRIPT_ANALYSIS *, WORD *, WORD *, SCRIPT_VISATTR *, int *);typedef HRESULT (WINAPI *pScriptPlace) (HDC, SCRIPT_CACHE *, const WORD *, int, const SCRIPT_VISATTR *, SCRIPT_ANALYSIS *, int *, GOFFSET *, ABC *);typedef HRESULT (WINAPI *pScriptFreeCache) (SCRIPT_CACHE *);typedef HRESULT (WINAPI *pScriptIsComplex) (WCHAR *, int, DWORD);static pScriptGetProperties script_get_properties;static pScriptItemize script_itemize;static pScriptShape script_shape;static pScriptPlace script_place;static pScriptFreeCache script_free_cache;static pScriptIsComplex script_is_complex;#ifdef BASIC_WIN32_DEBUGGINGstatic const SCRIPT_PROPERTIES **scripts;static int nscripts;#endif#endif#ifdef HAVE_USP10_Hstatic PangoEngineScriptInfo uniscribe_scripts[] = { /* We claim to cover everything ;-) */ { PANGO_SCRIPT_COMMON, "" },};#endifstatic PangoEngineScriptInfo basic_scripts[] = { /* Those characters that can be rendered legibly without Uniscribe. * I am not certain this list is correct. */ { PANGO_SCRIPT_ARMENIAN, "*" }, { PANGO_SCRIPT_BOPOMOFO, "*" }, { PANGO_SCRIPT_CHEROKEE, "*" }, { PANGO_SCRIPT_COPTIC, "*" }, { PANGO_SCRIPT_CYRILLIC, "*" }, { PANGO_SCRIPT_DESERET, "*" }, { PANGO_SCRIPT_ETHIOPIC, "*" }, { PANGO_SCRIPT_GEORGIAN, "*" }, { PANGO_SCRIPT_GOTHIC, "*" }, { PANGO_SCRIPT_GREEK, "*" }, { PANGO_SCRIPT_HAN, "*" }, { PANGO_SCRIPT_HANGUL, "*" }, { PANGO_SCRIPT_HIRAGANA, "*" }, { PANGO_SCRIPT_KATAKANA, "*" }, { PANGO_SCRIPT_LATIN, "*" }, { PANGO_SCRIPT_OGHAM, "*" }, { PANGO_SCRIPT_OLD_ITALIC, "*" }, { PANGO_SCRIPT_RUNIC, "*" }, { PANGO_SCRIPT_THAI, "*" }, { PANGO_SCRIPT_CANADIAN_ABORIGINAL, "*" }, { PANGO_SCRIPT_YI, "*" }, { PANGO_SCRIPT_BRAILLE, "*" }, { PANGO_SCRIPT_CYPRIOT, "*" }, { PANGO_SCRIPT_LIMBU, "*" }, { PANGO_SCRIPT_OSMANYA, "*" }, { PANGO_SCRIPT_SHAVIAN, "*" }, { PANGO_SCRIPT_LINEAR_B, "*" }, { PANGO_SCRIPT_UGARITIC, "*" }, /* Claim to handle everything as a fallback */ { PANGO_SCRIPT_COMMON, "" }};static PangoEngineInfo script_engines[] = { { SCRIPT_ENGINE_NAME, PANGO_ENGINE_TYPE_SHAPE, PANGO_RENDER_TYPE_WIN32, NULL, 0 }};static PangoGlyphfind_char (PangoFont *font, gunichar wc){ return pango_win32_font_get_glyph_index (font, wc);}static voidset_glyph (PangoFont *font, PangoGlyphString *glyphs, int i, int offset, PangoGlyph glyph){ PangoRectangle logical_rect; glyphs->glyphs[i].glyph = glyph; glyphs->glyphs[i].geometry.x_offset = 0; glyphs->glyphs[i].geometry.y_offset = 0; glyphs->log_clusters[i] = offset; pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect); glyphs->glyphs[i].geometry.width = logical_rect.width;}static voidswap_range (PangoGlyphString *glyphs, int start, int end){ int i, j; for (i = start, j = end - 1; i < j; i++, j--) { PangoGlyphInfo glyph_info; gint log_cluster; glyph_info = glyphs->glyphs[i]; glyphs->glyphs[i] = glyphs->glyphs[j]; glyphs->glyphs[j] = glyph_info; log_cluster = glyphs->log_clusters[i]; glyphs->log_clusters[i] = glyphs->log_clusters[j]; glyphs->log_clusters[j] = log_cluster; }}#ifdef BASIC_WIN32_DEBUGGING#if 0static char *charset_name (int charset){ static char unk[10]; switch (charset) {#define CASE(n) case n##_CHARSET: return #n CASE (ANSI); CASE (DEFAULT); CASE (SYMBOL); CASE (SHIFTJIS); CASE (HANGEUL); CASE (GB2312); CASE (CHINESEBIG5); CASE (OEM); CASE (JOHAB); CASE (HEBREW); CASE (ARABIC); CASE (GREEK); CASE (TURKISH); CASE (VIETNAMESE); CASE (THAI); CASE (EASTEUROPE); CASE (RUSSIAN); CASE (MAC); CASE (BALTIC);#undef CASE default: sprintf (unk, "%d", charset); return unk; }}#endifstatic char *lang_name (int lang){ static char unk[10]; switch (PRIMARYLANGID (lang)) {#define CASE(n) case LANG_##n: return #n CASE (NEUTRAL);#ifdef LANG_INVARIANT CASE (INVARIANT);#endif CASE (AFRIKAANS); CASE (ALBANIAN); CASE (ARABIC);#ifdef LANG_ARMENIAN CASE (ARMENIAN);#endif#ifdef LANG_ASSAMESE CASE (ASSAMESE);#endif#ifdef LANG_AZERI CASE (AZERI);#endif CASE (BASQUE); CASE (BELARUSIAN);#ifdef LANG_BENGALI CASE (BENGALI);#endif CASE (BULGARIAN); CASE (CATALAN); CASE (CHINESE); CASE (CROATIAN); CASE (CZECH); CASE (DANISH);#ifdef LANG_DIVEHI CASE (DIVEHI);#endif CASE (DUTCH); CASE (ENGLISH); CASE (ESTONIAN); CASE (FAEROESE); CASE (FARSI); CASE (FINNISH); CASE (FRENCH);#ifdef LANG_GALICIAN CASE (GALICIAN);#endif#ifdef LANG_GEORGIAN CASE (GEORGIAN);#endif CASE (GERMAN); CASE (GREEK);#ifdef LANG_GUJARATI CASE (GUJARATI);#endif CASE (HEBREW);#ifdef LANG_HINDI CASE (HINDI);#endif CASE (HUNGARIAN); CASE (ICELANDIC); CASE (INDONESIAN); CASE (ITALIAN); CASE (JAPANESE);#ifdef LANG_KANNADA CASE (KANNADA);#endif#ifdef LANG_KASHMIRI CASE (KASHMIRI);#endif#ifdef LANG_KAZAK CASE (KAZAK);#endif#ifdef LANG_KONKANI CASE (KONKANI);#endif CASE (KOREAN);#ifdef LANG_KYRGYZ CASE (KYRGYZ);#endif CASE (LATVIAN); CASE (LITHUANIAN);#ifdef LANG_MACEDONIAN CASE (MACEDONIAN);#endif#ifdef LANG_MALAY CASE (MALAY);#endif#ifdef LANG_MALAYALAM CASE (MALAYALAM);#endif#ifdef LANG_MANIPURI CASE (MANIPURI);#endif#ifdef LANG_MARATHI CASE (MARATHI);#endif#ifdef LANG_MONGOLIAN CASE (MONGOLIAN);#endif#ifdef LANG_NEPALI CASE (NEPALI);#endif CASE (NORWEGIAN);#ifdef LANG_ORIYA CASE (ORIYA);#endif CASE (POLISH); CASE (PORTUGUESE);#ifdef LANG_PUNJABI CASE (PUNJABI);#endif CASE (ROMANIAN); CASE (RUSSIAN);#ifdef LANG_SANSKRIT CASE (SANSKRIT);#endif#ifdef LANG_SINDHI CASE (SINDHI);#endif CASE (SLOVAK); CASE (SLOVENIAN); CASE (SPANISH);#ifdef LANG_SWAHILI CASE (SWAHILI);#endif CASE (SWEDISH);#ifdef LANG_SYRIAC CASE (SYRIAC);#endif#ifdef LANG_TAMIL CASE (TAMIL);#endif#ifdef LANG_TATAR CASE (TATAR);#endif#ifdef LANG_TELUGU CASE (TELUGU);#endif CASE (THAI); CASE (TURKISH); CASE (UKRAINIAN);#ifdef LANG_URDU CASE (URDU);#endif#ifdef LANG_UZBEK CASE (UZBEK);#endif CASE (VIETNAMESE);#undef CASE default: sprintf (unk, "%#02x", lang); return unk; }}#endif /* BASIC_WIN32_DEBUGGING */#ifdef HAVE_USP10_Hstatic WORDmake_langid (PangoLanguage *lang){#define CASE(t,p,s) if (pango_language_matches (lang, t)) return MAKELANGID (LANG_##p, SUBLANG_##p##_##s)#define CASEN(t,p) if (pango_language_matches (lang, t)) return MAKELANGID (LANG_##p, SUBLANG_NEUTRAL) /* Languages that most probably don't affect Uniscribe have been * left out. Uniscribe is documented to use * SCRIPT_CONTROL::uDefaultLanguage only to select digit shapes, so * just leave languages with own digits. */ CASEN ("ar", ARABIC); CASEN ("hy", ARMENIAN); CASEN ("as", ASSAMESE); CASEN ("az", AZERI); CASEN ("bn", BENGALI); CASE ("zh-tw", CHINESE, TRADITIONAL); CASE ("zh-cn", CHINESE, SIMPLIFIED); CASE ("zh-hk", CHINESE, HONGKONG); CASE ("zh-sg", CHINESE, SINGAPORE); CASE ("zh-mo", CHINESE, MACAU); CASEN ("dib", DIVEHI); CASEN ("fa", FARSI); CASEN ("ka", GEORGIAN); CASEN ("gu", GUJARATI); CASEN ("he", HEBREW); CASEN ("hi", HINDI); CASEN ("ja", JAPANESE); CASEN ("kn", KANNADA); CASE ("ks-in", KASHMIRI, INDIA); CASEN ("ks", KASHMIRI); CASEN ("kk", KAZAK); CASEN ("kok", KONKANI); CASEN ("ko", KOREAN); CASEN ("ky", KYRGYZ); CASEN ("ml", MALAYALAM); CASEN ("mni", MANIPURI); CASEN ("mr", MARATHI); CASEN ("mn", MONGOLIAN); CASE ("ne-in", NEPALI, INDIA); CASEN ("ne", NEPALI); CASEN ("or", ORIYA); CASEN ("pa", PUNJABI); CASEN ("sa", SANSKRIT); CASEN ("sd", SINDHI); CASEN ("syr", SYRIAC); CASEN ("ta", TAMIL); CASEN ("tt", TATAR); CASEN ("te", TELUGU); CASEN ("th", THAI); CASE ("ur-pk", URDU, PAKISTAN); CASE ("ur-in", URDU, INDIA); CASEN ("ur", URDU); CASEN ("uz", UZBEK);#undef CASE#undef CASEN return MAKELANGID (LANG_NEUTRAL, SUBLANG_NEUTRAL);}#ifdef BASIC_WIN32_DEBUGGINGstatic voiddump_glyphs_and_log_clusters (gboolean rtl, int itemlen, int charix0, WORD *log_clusters, WORD *iglyphs, int nglyphs){ if (pango_win32_debug) { int j, k, nclusters, clusterix, charix, ng; g_print (" ScriptShape: nglyphs=%d: ", nglyphs); for (j = 0; j < nglyphs; j++) g_print ("%d%s", iglyphs[j], (j < nglyphs-1) ? "," : ""); g_print ("\n"); g_print (" log_clusters: "); for (j = 0; j < itemlen; j++) g_print ("%d ", log_clusters[j]); g_print ("\n"); nclusters = 0; for (j = 0; j < itemlen; j++) { if (j == 0 || log_clusters[j-1] != log_clusters[j]) nclusters++; } g_print (" %d clusters:\n", nclusters); /* If RTL, first char is the last in the run, otherwise the * first. */ clusterix = 0; if (rtl) { int firstglyphix = 0; for (j = itemlen - 1, charix = charix0 + j; j >= 0; j--, charix--) { if (j == itemlen - 1 || log_clusters[j] != log_clusters[j+1]) g_print (" Cluster %d: chars %d--", clusterix, charix); if (j == 0 || log_clusters[j-1] != log_clusters[j]) { ng = log_clusters[j] - firstglyphix + 1; g_print ("%d: %d glyphs: ", charix, ng); for (k = firstglyphix; k <= log_clusters[j]; k++) { g_print ("%d", iglyphs[k]); if (k < log_clusters[j]) g_print (","); } firstglyphix = log_clusters[j] + 1; clusterix++; g_print ("\n"); } } } else { for (j = 0, charix = charix0; j < itemlen; j++, charix++) { if (j == 0 || log_clusters[j-1] != log_clusters[j]) g_print (" Cluster %d: wchar_t %d--", clusterix, charix); if (j == itemlen - 1 || log_clusters[j] != log_clusters[j+1]) { int klim = ((j == itemlen-1) ? nglyphs : log_clusters[j+1]); ng = klim - log_clusters[j]; g_print ("%d: %d glyphs: ", charix, ng); for (k = log_clusters[j]; k < klim; k++) { g_print ("%d", iglyphs[k]); if (k != klim - 1) g_print (","); } clusterix++; g_print ("\n"); } } } }}#endif /* BASIC_WIN32_DEBUGGING */static intunichar_index (wchar_t *wtext, int ix){ int i, index;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -