1/* 2 3Copyright 1990, 1994, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from The Open Group. 26 27*/ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32 33#include "fntfilst.h" 34#include "bitmap.h" 35#include "bdfint.h" 36 37#ifndef MAXSHORT 38#define MAXSHORT 32767 39#endif 40 41#ifndef MINSHORT 42#define MINSHORT -32768 43#endif 44 45static xCharInfo initMinMetrics = { 46 MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF 47}; 48 49static xCharInfo initMaxMetrics = { 50 MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000 51}; 52 53#define MINMAX(field,ci) \ 54 if (minbounds->field > (ci)->field) \ 55 minbounds->field = (ci)->field; \ 56 if (maxbounds->field < (ci)->field) \ 57 maxbounds->field = (ci)->field; 58 59#define COMPUTE_MINMAX(ci) \ 60 if ((ci)->ascent || (ci)->descent || \ 61 (ci)->leftSideBearing || (ci)->rightSideBearing || \ 62 (ci)->characterWidth) \ 63 { \ 64 MINMAX(ascent, (ci)); \ 65 MINMAX(descent, (ci)); \ 66 MINMAX(leftSideBearing, (ci)); \ 67 MINMAX(rightSideBearing, (ci)); \ 68 MINMAX(characterWidth, (ci)); \ 69 } 70 71void 72bitmapComputeFontBounds(FontPtr pFont) 73{ 74 BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 75 int nchars; 76 CharInfoPtr ci; 77 int maxOverlap; 78 int overlap; 79 xCharInfo *minbounds, *maxbounds; 80 int i; 81 int numneg = 0, numpos = 0; 82 83 if (bitmapFont->bitmapExtra) { 84 minbounds = &bitmapFont->bitmapExtra->info.minbounds; 85 maxbounds = &bitmapFont->bitmapExtra->info.maxbounds; 86 } 87 else { 88 minbounds = &pFont->info.minbounds; 89 maxbounds = &pFont->info.maxbounds; 90 } 91 *minbounds = initMinMetrics; 92 *maxbounds = initMaxMetrics; 93 maxOverlap = MINSHORT; 94 nchars = bitmapFont->num_chars; 95 for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) { 96 COMPUTE_MINMAX(&ci->metrics); 97 if (ci->metrics.characterWidth < 0) 98 numneg++; 99 else 100 numpos++; 101 minbounds->attributes &= ci->metrics.attributes; 102 maxbounds->attributes |= ci->metrics.attributes; 103 overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth; 104 if (maxOverlap < overlap) 105 maxOverlap = overlap; 106 } 107 if (bitmapFont->bitmapExtra) { 108 if (numneg > numpos) 109 bitmapFont->bitmapExtra->info.drawDirection = RightToLeft; 110 else 111 bitmapFont->bitmapExtra->info.drawDirection = LeftToRight; 112 bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap; 113 minbounds = &pFont->info.minbounds; 114 maxbounds = &pFont->info.maxbounds; 115 *minbounds = initMinMetrics; 116 *maxbounds = initMaxMetrics; 117 i = 0; 118 maxOverlap = MINSHORT; 119 for (int r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) { 120 for (int c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) { 121 ci = ACCESSENCODING(bitmapFont->encoding, i); 122 if (ci) { 123 COMPUTE_MINMAX(&ci->metrics); 124 if (ci->metrics.characterWidth < 0) 125 numneg++; 126 else 127 numpos++; 128 minbounds->attributes &= ci->metrics.attributes; 129 maxbounds->attributes |= ci->metrics.attributes; 130 overlap = ci->metrics.rightSideBearing - 131 ci->metrics.characterWidth; 132 if (maxOverlap < overlap) 133 maxOverlap = overlap; 134 } 135 i++; 136 } 137 } 138 } 139 if (numneg > numpos) 140 pFont->info.drawDirection = RightToLeft; 141 else 142 pFont->info.drawDirection = LeftToRight; 143 pFont->info.maxOverlap = maxOverlap; 144} 145 146void 147bitmapComputeFontInkBounds(FontPtr pFont) 148{ 149 BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 150 151 if (!bitmapFont->ink_metrics) { 152 if (bitmapFont->bitmapExtra) { 153 bitmapFont->bitmapExtra->info.ink_minbounds = 154 bitmapFont->bitmapExtra->info.minbounds; 155 bitmapFont->bitmapExtra->info.ink_maxbounds = 156 bitmapFont->bitmapExtra->info.maxbounds; 157 } 158 pFont->info.ink_minbounds = pFont->info.minbounds; 159 pFont->info.ink_maxbounds = pFont->info.maxbounds; 160 } 161 else { 162 xCharInfo *minbounds, *maxbounds, *ci; 163 int nchars, i; 164 165 if (bitmapFont->bitmapExtra) { 166 minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds; 167 maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds; 168 } 169 else { 170 minbounds = &pFont->info.ink_minbounds; 171 maxbounds = &pFont->info.ink_maxbounds; 172 } 173 *minbounds = initMinMetrics; 174 *maxbounds = initMaxMetrics; 175 nchars = bitmapFont->num_chars; 176 for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) { 177 COMPUTE_MINMAX(ci); 178 minbounds->attributes &= ci->attributes; 179 maxbounds->attributes |= ci->attributes; 180 } 181 if (bitmapFont->bitmapExtra) { 182 minbounds = &pFont->info.ink_minbounds; 183 maxbounds = &pFont->info.ink_maxbounds; 184 *minbounds = initMinMetrics; 185 *maxbounds = initMaxMetrics; 186 i = 0; 187 for (int r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) { 188 for (int c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) 189 { 190 CharInfoPtr cit = ACCESSENCODING(bitmapFont->encoding, i); 191 if (cit) { 192 int offset = cit - bitmapFont->metrics; 193 ci = &bitmapFont->ink_metrics[offset]; 194 COMPUTE_MINMAX(ci); 195 minbounds->attributes &= ci->attributes; 196 maxbounds->attributes |= ci->attributes; 197 } 198 i++; 199 } 200 } 201 } 202 } 203} 204 205Bool 206bitmapAddInkMetrics(FontPtr pFont) 207{ 208 BitmapFontPtr bitmapFont; 209 210 bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 211 bitmapFont->ink_metrics = malloc(bitmapFont->num_chars * sizeof(xCharInfo)); 212 if (!bitmapFont->ink_metrics) { 213 fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n", 214 bitmapFont->num_chars, (unsigned long) sizeof(xCharInfo)); 215 return FALSE; 216 } 217 for (int i = 0; i < bitmapFont->num_chars; i++) 218 FontCharInkMetrics(pFont, &bitmapFont->metrics[i], 219 &bitmapFont->ink_metrics[i]); 220 pFont->info.inkMetrics = TRUE; 221 return TRUE; 222} 223 224/* ARGSUSED */ 225int 226bitmapComputeWeight(FontPtr pFont) 227{ 228 return 10; 229} 230