summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu-xetex/samples/layout/FontMap.cpp
diff options
context:
space:
mode:
authorJonathan Kew <jfkthame@googlemail.com>2008-03-04 13:26:36 +0000
committerJonathan Kew <jfkthame@googlemail.com>2008-03-04 13:26:36 +0000
commit53790d2a0c50915d8cec71df3e89cd24d887b2fe (patch)
tree16f6b4df067eb3c2024e0a7735cb7ccea86b3aba /Build/source/libs/icu-xetex/samples/layout/FontMap.cpp
parentf483a5de9331a257f597282e611ecfb63f5ab118 (diff)
update icu-xetex to 3.8.1-based code from xetex repository
git-svn-id: svn://tug.org/texlive/trunk@6842 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/icu-xetex/samples/layout/FontMap.cpp')
-rw-r--r--Build/source/libs/icu-xetex/samples/layout/FontMap.cpp287
1 files changed, 287 insertions, 0 deletions
diff --git a/Build/source/libs/icu-xetex/samples/layout/FontMap.cpp b/Build/source/libs/icu-xetex/samples/layout/FontMap.cpp
new file mode 100644
index 00000000000..1510b29b2da
--- /dev/null
+++ b/Build/source/libs/icu-xetex/samples/layout/FontMap.cpp
@@ -0,0 +1,287 @@
+/*
+ ******************************************************************************
+ * Copyright (C) 1998-2006, International Business Machines Corporation and *
+ * others. All Rights Reserved. *
+ ******************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "unicode/utypes.h"
+#include "unicode/uscript.h"
+
+#include "layout/LETypes.h"
+#include "layout/LEScripts.h"
+#include "layout/LEFontInstance.h"
+
+#include "GUISupport.h"
+#include "FontMap.h"
+
+FontMap::FontMap(const char *fileName, le_int16 pointSize, GUISupport *guiSupport, LEErrorCode &status)
+ : fPointSize(pointSize), fFontCount(0), fAscent(0), fDescent(0), fLeading(0), fGUISupport(guiSupport)
+{
+ le_int32 defaultFont = -1, i, script;
+ le_bool haveFonts = FALSE;
+
+/**/
+ for (i = 0; i < scriptCodeCount; i += 1) {
+ fFontIndices[i] = -1;
+ fFontNames[i] = NULL;
+ fFontInstances[i] = NULL;
+ }
+ /**/
+
+ if (LE_FAILURE(status)) {
+ return;
+ }
+
+ char *c, *scriptName, *fontName, *line, buffer[BUFFER_SIZE];
+ FILE *file;
+
+ file = fopen(fileName, "r");
+
+ if (file == NULL) {
+ sprintf(errorMessage, "Could not open the font map file: %s.", fileName);
+ fGUISupport->postErrorMessage(errorMessage, "Font Map Error");
+ status = LE_FONT_FILE_NOT_FOUND_ERROR;
+ return;
+ }
+
+ while (fgets(buffer, BUFFER_SIZE, file) != NULL) {
+ UScriptCode scriptCode;
+ UErrorCode scriptStatus = U_ZERO_ERROR;
+
+ line = strip(buffer);
+ if (line[0] == '#' || line[0] == 0) {
+ continue;
+ }
+
+ c = strchr(line, ':');
+ c[0] = 0;
+
+ fontName = strip(&c[1]);
+ scriptName = strip(line);
+
+ if (strcmp(scriptName, "DEFAULT") == 0) {
+ defaultFont = getFontIndex(fontName);
+ haveFonts = TRUE;
+ continue;
+ }
+
+ le_int32 fillCount = uscript_getCode(scriptName, &scriptCode, 1, &scriptStatus);
+
+ if (U_FAILURE(scriptStatus) || fillCount <= 0 ||
+ scriptStatus == U_USING_FALLBACK_WARNING || scriptStatus == U_USING_DEFAULT_WARNING) {
+ sprintf(errorMessage, "The script name %s is invalid.", line);
+ fGUISupport->postErrorMessage(errorMessage, "Font Map Error");
+ continue;
+ }
+
+ script = (le_int32) scriptCode;
+
+ if (fFontIndices[script] >= 0) {
+ // FIXME: complain that this is a duplicate entry and bail (?)
+ fFontIndices[script] = -1;
+ }
+
+ fFontIndices[script] = getFontIndex(fontName);
+ haveFonts = TRUE;
+ }
+
+ if (defaultFont >= 0) {
+ for (script = 0; script < scriptCodeCount; script += 1) {
+ if (fFontIndices[script] < 0) {
+ fFontIndices[script] = defaultFont;
+ }
+ }
+ }
+
+ if (! haveFonts) {
+ sprintf(errorMessage, "The font map file %s does not contain any valid scripts.", fileName);
+ fGUISupport->postErrorMessage(errorMessage, "Font Map Error");
+ status = LE_ILLEGAL_ARGUMENT_ERROR;
+ }
+
+ fclose(file);
+}
+
+FontMap::~FontMap()
+{
+ le_int32 font;
+
+ for (font = 0; font < fFontCount; font += 1) {
+ if (fFontNames[font] != NULL) {
+ delete[] (char *) fFontNames[font];
+ }
+ }
+
+ for (font = 0; font < fFontCount; font += 1) {
+ if (fFontInstances[font] != NULL) {
+ delete fFontInstances[font];
+ }
+ }
+}
+
+le_int32 FontMap::getFontIndex(const char *fontName)
+{
+ le_int32 index;
+
+ for (index = 0; index < fFontCount; index += 1) {
+ if (strcmp(fontName, fFontNames[index]) == 0) {
+ return index;
+ }
+ }
+
+ if (fFontCount < (le_int32) scriptCodeCount) {
+ index = fFontCount++;
+ } else {
+ // The font name table is full. Since there can
+ // only be scriptCodeCount fonts in use at once,
+ // there should be at least one that's not being
+ // referenced; find it and resue it's index.
+
+ for (index = 0; index < fFontCount; index += 1) {
+ le_int32 script;
+
+ for (script = 0; script < scriptCodeCount; script += 1) {
+ if (fFontIndices[script] == index) {
+ break;
+ }
+ }
+
+ if (script >= scriptCodeCount) {
+ break;
+ }
+ }
+ }
+
+ if (index >= scriptCodeCount) {
+ return -1;
+ }
+
+ le_int32 len = strlen(fontName);
+ char *s = new char[len + 1];
+
+ fFontNames[index] = strcpy(s, fontName);
+ return index;
+}
+
+char *FontMap::strip(char *s)
+{
+ le_int32 start, end, len;
+
+ start = 0;
+ len = strlen(s);
+
+ while (start < len && isspace(s[start])) {
+ start += 1;
+ }
+
+ end = len - 1;
+
+ while (end > start && isspace(s[end])) {
+ end -= 1;
+ }
+
+ if (end < len) {
+ s[end + 1] = '\0';
+ }
+
+ return &s[start];
+}
+
+const LEFontInstance *FontMap::getScriptFont(le_int32 scriptCode, LEErrorCode &status)
+{
+ if (LE_FAILURE(status)) {
+ return NULL;
+ }
+
+ if (scriptCode <= -1 || scriptCode >= scriptCodeCount) {
+ status = LE_ILLEGAL_ARGUMENT_ERROR;
+ return NULL;
+ }
+
+
+ le_int32 fontIndex = fFontIndices[scriptCode];
+
+ if (fontIndex < 0) {
+ sprintf(errorMessage, "No font was set for script %s", uscript_getName((UScriptCode) scriptCode));
+ fGUISupport->postErrorMessage(errorMessage, "Font Map Error");
+ status = LE_FONT_FILE_NOT_FOUND_ERROR;
+ return NULL;
+ }
+
+ if (fFontInstances[fontIndex] == NULL) {
+ fFontInstances[fontIndex] = openFont(fFontNames[fontIndex], fPointSize, status);
+
+ if (LE_FAILURE(status)) {
+ sprintf(errorMessage, "Could not open font file %s", fFontNames[fontIndex]);
+ fGUISupport->postErrorMessage(errorMessage, "Font Map Error");
+ return NULL;
+ }
+ }
+
+ return fFontInstances[fontIndex];
+}
+
+le_int32 FontMap::getAscent() const
+{
+ if (fAscent <= 0) {
+ ((FontMap *) this)->getMaxMetrics();
+ }
+
+ return fAscent;
+}
+
+le_int32 FontMap::getDescent() const
+{
+ if (fDescent <= 0) {
+ ((FontMap *) this)->getMaxMetrics();
+ }
+
+ return fDescent;
+}
+
+le_int32 FontMap::getLeading() const
+{
+ if (fLeading <= 0) {
+ ((FontMap *) this)->getMaxMetrics();
+ }
+
+ return fLeading;
+}
+
+void FontMap::getMaxMetrics()
+{
+ for (le_int32 i = 0; i < fFontCount; i += 1) {
+ LEErrorCode status = LE_NO_ERROR;
+ le_int32 ascent, descent, leading;
+
+ if (fFontInstances[i] == NULL) {
+ fFontInstances[i] = openFont(fFontNames[i], fPointSize, status);
+
+ if (LE_FAILURE(status)) {
+ continue;
+ }
+ }
+
+ ascent = fFontInstances[i]->getAscent();
+ descent = fFontInstances[i]->getDescent();
+ leading = fFontInstances[i]->getLeading();
+
+ if (ascent > fAscent) {
+ fAscent = ascent;
+ }
+
+ if (descent > fDescent) {
+ fDescent = descent;
+ }
+
+ if (leading > fLeading) {
+ fLeading = leading;
+ }
+ }
+}
+