bitmaputil.c revision a96d7823
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#include "libxfontint.h" 33 34#include <X11/fonts/fntfilst.h> 35#include <X11/fonts/bitmap.h> 36#include <X11/fonts/bdfint.h> 37 38#ifndef MAXSHORT 39#define MAXSHORT 32767 40#endif 41 42#ifndef MINSHORT 43#define MINSHORT -32768 44#endif 45 46static xCharInfo initMinMetrics = { 47MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF}; 48static xCharInfo initMaxMetrics = { 49MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000}; 50 51#define MINMAX(field,ci) \ 52 if (minbounds->field > (ci)->field) \ 53 minbounds->field = (ci)->field; \ 54 if (maxbounds->field < (ci)->field) \ 55 maxbounds->field = (ci)->field; 56 57#define COMPUTE_MINMAX(ci) \ 58 if ((ci)->ascent || (ci)->descent || \ 59 (ci)->leftSideBearing || (ci)->rightSideBearing || \ 60 (ci)->characterWidth) \ 61 { \ 62 MINMAX(ascent, (ci)); \ 63 MINMAX(descent, (ci)); \ 64 MINMAX(leftSideBearing, (ci)); \ 65 MINMAX(rightSideBearing, (ci)); \ 66 MINMAX(characterWidth, (ci)); \ 67 } 68 69void 70bitmapComputeFontBounds(FontPtr pFont) 71{ 72 BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 73 int nchars; 74 int r, 75 c; 76 CharInfoPtr ci; 77 int maxOverlap; 78 int overlap; 79 xCharInfo *minbounds, 80 *maxbounds; 81 int i; 82 int numneg = 0, numpos = 0; 83 84 if (bitmapFont->bitmapExtra) { 85 minbounds = &bitmapFont->bitmapExtra->info.minbounds; 86 maxbounds = &bitmapFont->bitmapExtra->info.maxbounds; 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 (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) { 120 for (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 int nchars; 151 int r, 152 c; 153 CharInfoPtr cit; 154 xCharInfo *ci; 155 int offset; 156 xCharInfo *minbounds, 157 *maxbounds; 158 int i; 159 160 if (!bitmapFont->ink_metrics) { 161 if (bitmapFont->bitmapExtra) { 162 bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds; 163 bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds; 164 } 165 pFont->info.ink_minbounds = pFont->info.minbounds; 166 pFont->info.ink_maxbounds = pFont->info.maxbounds; 167 } else { 168 if (bitmapFont->bitmapExtra) { 169 minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds; 170 maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds; 171 } else { 172 minbounds = &pFont->info.ink_minbounds; 173 maxbounds = &pFont->info.ink_maxbounds; 174 } 175 *minbounds = initMinMetrics; 176 *maxbounds = initMaxMetrics; 177 nchars = bitmapFont->num_chars; 178 for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) { 179 COMPUTE_MINMAX(ci); 180 minbounds->attributes &= ci->attributes; 181 maxbounds->attributes |= ci->attributes; 182 } 183 if (bitmapFont->bitmapExtra) { 184 minbounds = &pFont->info.ink_minbounds; 185 maxbounds = &pFont->info.ink_maxbounds; 186 *minbounds = initMinMetrics; 187 *maxbounds = initMaxMetrics; 188 i=0; 189 for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) { 190 for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) { 191 cit = ACCESSENCODING(bitmapFont->encoding, i); 192 if (cit) { 193 offset = cit - bitmapFont->metrics; 194 ci = &bitmapFont->ink_metrics[offset]; 195 COMPUTE_MINMAX(ci); 196 minbounds->attributes &= ci->attributes; 197 maxbounds->attributes |= ci->attributes; 198 } 199 i++; 200 } 201 } 202 } 203 } 204} 205 206Bool 207bitmapAddInkMetrics(FontPtr pFont) 208{ 209 BitmapFontPtr bitmapFont; 210 int i; 211 212 bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 213 bitmapFont->ink_metrics = malloc(bitmapFont->num_chars * sizeof(xCharInfo)); 214 if (!bitmapFont->ink_metrics) { 215 fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n", 216 bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo)); 217 return FALSE; 218 } 219 for (i = 0; i < bitmapFont->num_chars; i++) 220 FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]); 221 pFont->info.inkMetrics = TRUE; 222 return TRUE; 223} 224 225/* ARGSUSED */ 226int 227bitmapComputeWeight(FontPtr pFont) 228{ 229 return 10; 230} 231