bitmaputil.c revision 23a0898a
123a0898aSmrg/* $Xorg: bitmaputil.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */ 223a0898aSmrg 323a0898aSmrg/* 423a0898aSmrg 523a0898aSmrgCopyright 1990, 1994, 1998 The Open Group 623a0898aSmrg 723a0898aSmrgPermission to use, copy, modify, distribute, and sell this software and its 823a0898aSmrgdocumentation for any purpose is hereby granted without fee, provided that 923a0898aSmrgthe above copyright notice appear in all copies and that both that 1023a0898aSmrgcopyright notice and this permission notice appear in supporting 1123a0898aSmrgdocumentation. 1223a0898aSmrg 1323a0898aSmrgThe above copyright notice and this permission notice shall be included 1423a0898aSmrgin all copies or substantial portions of the Software. 1523a0898aSmrg 1623a0898aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1723a0898aSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1823a0898aSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1923a0898aSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 2023a0898aSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2123a0898aSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2223a0898aSmrgOTHER DEALINGS IN THE SOFTWARE. 2323a0898aSmrg 2423a0898aSmrgExcept as contained in this notice, the name of The Open Group shall 2523a0898aSmrgnot be used in advertising or otherwise to promote the sale, use or 2623a0898aSmrgother dealings in this Software without prior written authorization 2723a0898aSmrgfrom The Open Group. 2823a0898aSmrg 2923a0898aSmrg*/ 3023a0898aSmrg/* $XFree86: xc/lib/font/bitmap/bitmaputil.c,v 1.10 2002/09/24 20:52:48 tsi Exp $ */ 3123a0898aSmrg 3223a0898aSmrg#ifdef HAVE_CONFIG_H 3323a0898aSmrg#include <config.h> 3423a0898aSmrg#endif 3523a0898aSmrg 3623a0898aSmrg#include <X11/fonts/fntfilst.h> 3723a0898aSmrg#include <X11/fonts/bitmap.h> 3823a0898aSmrg#include <X11/fonts/bdfint.h> 3923a0898aSmrg 4023a0898aSmrg#ifndef MAXSHORT 4123a0898aSmrg#define MAXSHORT 32767 4223a0898aSmrg#endif 4323a0898aSmrg 4423a0898aSmrg#ifndef MINSHORT 4523a0898aSmrg#define MINSHORT -32768 4623a0898aSmrg#endif 4723a0898aSmrg 4823a0898aSmrgstatic xCharInfo initMinMetrics = { 4923a0898aSmrgMAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF}; 5023a0898aSmrgstatic xCharInfo initMaxMetrics = { 5123a0898aSmrgMINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000}; 5223a0898aSmrg 5323a0898aSmrg#define MINMAX(field,ci) \ 5423a0898aSmrg if (minbounds->field > (ci)->field) \ 5523a0898aSmrg minbounds->field = (ci)->field; \ 5623a0898aSmrg if (maxbounds->field < (ci)->field) \ 5723a0898aSmrg maxbounds->field = (ci)->field; 5823a0898aSmrg 5923a0898aSmrg#define COMPUTE_MINMAX(ci) \ 6023a0898aSmrg if ((ci)->ascent || (ci)->descent || \ 6123a0898aSmrg (ci)->leftSideBearing || (ci)->rightSideBearing || \ 6223a0898aSmrg (ci)->characterWidth) \ 6323a0898aSmrg { \ 6423a0898aSmrg MINMAX(ascent, (ci)); \ 6523a0898aSmrg MINMAX(descent, (ci)); \ 6623a0898aSmrg MINMAX(leftSideBearing, (ci)); \ 6723a0898aSmrg MINMAX(rightSideBearing, (ci)); \ 6823a0898aSmrg MINMAX(characterWidth, (ci)); \ 6923a0898aSmrg } 7023a0898aSmrg 7123a0898aSmrgvoid 7223a0898aSmrgbitmapComputeFontBounds(FontPtr pFont) 7323a0898aSmrg{ 7423a0898aSmrg BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 7523a0898aSmrg int nchars; 7623a0898aSmrg int r, 7723a0898aSmrg c; 7823a0898aSmrg CharInfoPtr ci; 7923a0898aSmrg int maxOverlap; 8023a0898aSmrg int overlap; 8123a0898aSmrg xCharInfo *minbounds, 8223a0898aSmrg *maxbounds; 8323a0898aSmrg int i; 8423a0898aSmrg int numneg = 0, numpos = 0; 8523a0898aSmrg 8623a0898aSmrg if (bitmapFont->bitmapExtra) { 8723a0898aSmrg minbounds = &bitmapFont->bitmapExtra->info.minbounds; 8823a0898aSmrg maxbounds = &bitmapFont->bitmapExtra->info.maxbounds; 8923a0898aSmrg } else { 9023a0898aSmrg minbounds = &pFont->info.minbounds; 9123a0898aSmrg maxbounds = &pFont->info.maxbounds; 9223a0898aSmrg } 9323a0898aSmrg *minbounds = initMinMetrics; 9423a0898aSmrg *maxbounds = initMaxMetrics; 9523a0898aSmrg maxOverlap = MINSHORT; 9623a0898aSmrg nchars = bitmapFont->num_chars; 9723a0898aSmrg for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) { 9823a0898aSmrg COMPUTE_MINMAX(&ci->metrics); 9923a0898aSmrg if (ci->metrics.characterWidth < 0) 10023a0898aSmrg numneg++; 10123a0898aSmrg else 10223a0898aSmrg numpos++; 10323a0898aSmrg minbounds->attributes &= ci->metrics.attributes; 10423a0898aSmrg maxbounds->attributes |= ci->metrics.attributes; 10523a0898aSmrg overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth; 10623a0898aSmrg if (maxOverlap < overlap) 10723a0898aSmrg maxOverlap = overlap; 10823a0898aSmrg } 10923a0898aSmrg if (bitmapFont->bitmapExtra) { 11023a0898aSmrg if (numneg > numpos) 11123a0898aSmrg bitmapFont->bitmapExtra->info.drawDirection = RightToLeft; 11223a0898aSmrg else 11323a0898aSmrg bitmapFont->bitmapExtra->info.drawDirection = LeftToRight; 11423a0898aSmrg bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap; 11523a0898aSmrg minbounds = &pFont->info.minbounds; 11623a0898aSmrg maxbounds = &pFont->info.maxbounds; 11723a0898aSmrg *minbounds = initMinMetrics; 11823a0898aSmrg *maxbounds = initMaxMetrics; 11923a0898aSmrg i = 0; 12023a0898aSmrg maxOverlap = MINSHORT; 12123a0898aSmrg for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) { 12223a0898aSmrg for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) { 12323a0898aSmrg ci = ACCESSENCODING(bitmapFont->encoding, i); 12423a0898aSmrg if (ci) { 12523a0898aSmrg COMPUTE_MINMAX(&ci->metrics); 12623a0898aSmrg if (ci->metrics.characterWidth < 0) 12723a0898aSmrg numneg++; 12823a0898aSmrg else 12923a0898aSmrg numpos++; 13023a0898aSmrg minbounds->attributes &= ci->metrics.attributes; 13123a0898aSmrg maxbounds->attributes |= ci->metrics.attributes; 13223a0898aSmrg overlap = ci->metrics.rightSideBearing - 13323a0898aSmrg ci->metrics.characterWidth; 13423a0898aSmrg if (maxOverlap < overlap) 13523a0898aSmrg maxOverlap = overlap; 13623a0898aSmrg } 13723a0898aSmrg i++; 13823a0898aSmrg } 13923a0898aSmrg } 14023a0898aSmrg } 14123a0898aSmrg if (numneg > numpos) 14223a0898aSmrg pFont->info.drawDirection = RightToLeft; 14323a0898aSmrg else 14423a0898aSmrg pFont->info.drawDirection = LeftToRight; 14523a0898aSmrg pFont->info.maxOverlap = maxOverlap; 14623a0898aSmrg} 14723a0898aSmrg 14823a0898aSmrgvoid 14923a0898aSmrgbitmapComputeFontInkBounds(FontPtr pFont) 15023a0898aSmrg{ 15123a0898aSmrg BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 15223a0898aSmrg int nchars; 15323a0898aSmrg int r, 15423a0898aSmrg c; 15523a0898aSmrg CharInfoPtr cit; 15623a0898aSmrg xCharInfo *ci; 15723a0898aSmrg int offset; 15823a0898aSmrg xCharInfo *minbounds, 15923a0898aSmrg *maxbounds; 16023a0898aSmrg int i; 16123a0898aSmrg 16223a0898aSmrg if (!bitmapFont->ink_metrics) { 16323a0898aSmrg if (bitmapFont->bitmapExtra) { 16423a0898aSmrg bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds; 16523a0898aSmrg bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds; 16623a0898aSmrg } 16723a0898aSmrg pFont->info.ink_minbounds = pFont->info.minbounds; 16823a0898aSmrg pFont->info.ink_maxbounds = pFont->info.maxbounds; 16923a0898aSmrg } else { 17023a0898aSmrg if (bitmapFont->bitmapExtra) { 17123a0898aSmrg minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds; 17223a0898aSmrg maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds; 17323a0898aSmrg } else { 17423a0898aSmrg minbounds = &pFont->info.ink_minbounds; 17523a0898aSmrg maxbounds = &pFont->info.ink_maxbounds; 17623a0898aSmrg } 17723a0898aSmrg *minbounds = initMinMetrics; 17823a0898aSmrg *maxbounds = initMaxMetrics; 17923a0898aSmrg nchars = bitmapFont->num_chars; 18023a0898aSmrg for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) { 18123a0898aSmrg COMPUTE_MINMAX(ci); 18223a0898aSmrg minbounds->attributes &= ci->attributes; 18323a0898aSmrg maxbounds->attributes |= ci->attributes; 18423a0898aSmrg } 18523a0898aSmrg if (bitmapFont->bitmapExtra) { 18623a0898aSmrg minbounds = &pFont->info.ink_minbounds; 18723a0898aSmrg maxbounds = &pFont->info.ink_maxbounds; 18823a0898aSmrg *minbounds = initMinMetrics; 18923a0898aSmrg *maxbounds = initMaxMetrics; 19023a0898aSmrg i=0; 19123a0898aSmrg for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) { 19223a0898aSmrg for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) { 19323a0898aSmrg cit = ACCESSENCODING(bitmapFont->encoding, i); 19423a0898aSmrg if (cit) { 19523a0898aSmrg offset = cit - bitmapFont->metrics; 19623a0898aSmrg ci = &bitmapFont->ink_metrics[offset]; 19723a0898aSmrg COMPUTE_MINMAX(ci); 19823a0898aSmrg minbounds->attributes &= ci->attributes; 19923a0898aSmrg maxbounds->attributes |= ci->attributes; 20023a0898aSmrg } 20123a0898aSmrg i++; 20223a0898aSmrg } 20323a0898aSmrg } 20423a0898aSmrg } 20523a0898aSmrg } 20623a0898aSmrg} 20723a0898aSmrg 20823a0898aSmrgBool 20923a0898aSmrgbitmapAddInkMetrics(FontPtr pFont) 21023a0898aSmrg{ 21123a0898aSmrg BitmapFontPtr bitmapFont; 21223a0898aSmrg int i; 21323a0898aSmrg 21423a0898aSmrg bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 21523a0898aSmrg bitmapFont->ink_metrics = (xCharInfo *) xalloc(bitmapFont->num_chars * sizeof(xCharInfo)); 21623a0898aSmrg if (!bitmapFont->ink_metrics) { 21723a0898aSmrg fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n", 21823a0898aSmrg bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo)); 21923a0898aSmrg return FALSE; 22023a0898aSmrg } 22123a0898aSmrg for (i = 0; i < bitmapFont->num_chars; i++) 22223a0898aSmrg FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]); 22323a0898aSmrg pFont->info.inkMetrics = TRUE; 22423a0898aSmrg return TRUE; 22523a0898aSmrg} 22623a0898aSmrg 22723a0898aSmrg/* ARGSUSED */ 22823a0898aSmrgint 22923a0898aSmrgbitmapComputeWeight(FontPtr pFont) 23023a0898aSmrg{ 23123a0898aSmrg return 10; 23223a0898aSmrg} 233