Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /*********************************************************** |
2 | ||
3 | Copyright 1987, 1998 The Open Group | |
4 | ||
5 | Permission to use, copy, modify, distribute, and sell this software and its | |
6 | documentation for any purpose is hereby granted without fee, provided that | |
7 | the above copyright notice appear in all copies and that both that | |
8 | copyright notice and this permission notice appear in supporting | |
9 | documentation. | |
10 | ||
11 | The above copyright notice and this permission notice shall be included in | |
12 | all copies or substantial portions of the Software. | |
13 | ||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |
18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
20 | ||
21 | Except as contained in this notice, the name of The Open Group shall not be | |
22 | used in advertising or otherwise to promote the sale, use or other dealings | |
23 | in this Software without prior written authorization from The Open Group. | |
24 | ||
25 | Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. | |
26 | ||
27 | All Rights Reserved | |
28 | ||
29 | Permission to use, copy, modify, and distribute this software and its | |
30 | documentation for any purpose and without fee is hereby granted, | |
31 | provided that the above copyright notice appear in all copies and that | |
32 | both that copyright notice and this permission notice appear in | |
33 | supporting documentation, and that the name of Digital not be | |
34 | used in advertising or publicity pertaining to distribution of the | |
35 | software without specific, written prior permission. | |
36 | ||
37 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
38 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
39 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
40 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
41 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
42 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
43 | SOFTWARE. | |
44 | ||
45 | ******************************************************************/ | |
46 | ||
47 | #ifdef HAVE_DIX_CONFIG_H | |
48 | #include <dix-config.h> | |
49 | #endif | |
50 | ||
51 | #include <X11/X.h> | |
52 | #include <X11/Xmd.h> | |
53 | #include <X11/Xproto.h> | |
54 | #include "misc.h" | |
55 | #include <X11/fonts/fontstruct.h> | |
56 | #include "dixfontstr.h" | |
57 | #include "gcstruct.h" | |
58 | #include "windowstr.h" | |
59 | #include "scrnintstr.h" | |
60 | #include "pixmap.h" | |
61 | #include "servermd.h" | |
62 | #include "mi.h" | |
63 | ||
64 | /* | |
65 | machine-independent glyph blt. | |
66 | assumes that glyph bits in snf are written in bytes, | |
67 | have same bit order as the server's bitmap format, | |
68 | and are byte padded. this corresponds to the snf distributed | |
69 | with the sample server. | |
70 | ||
71 | get a scratch GC. | |
72 | in the scratch GC set alu = GXcopy, fg = 1, bg = 0 | |
73 | allocate a bitmap big enough to hold the largest glyph in the font | |
74 | validate the scratch gc with the bitmap | |
75 | for each glyph | |
76 | carefully put the bits of the glyph in a buffer, | |
77 | padded to the server pixmap scanline padding rules | |
78 | fake a call to PutImage from the buffer into the bitmap | |
79 | use the bitmap in a call to PushPixels | |
80 | */ | |
81 | ||
82 | void | |
83 | miPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, /* array of character info */ | |
84 | pointer pglyphBase /* start of array of glyphs */ | |
85 | ) | |
86 | { | |
87 | int width, height; | |
88 | PixmapPtr pPixmap; | |
89 | int nbyLine; /* bytes per line of padded pixmap */ | |
90 | FontPtr pfont; | |
91 | GCPtr pGCtmp; | |
92 | int i; | |
93 | int j; | |
94 | unsigned char *pbits; /* buffer for PutImage */ | |
95 | unsigned char *pb; /* temp pointer into buffer */ | |
96 | CharInfoPtr pci; /* currect char info */ | |
97 | unsigned char *pglyph; /* pointer bits in glyph */ | |
98 | int gWidth, gHeight; /* width and height of glyph */ | |
99 | int nbyGlyphWidth; /* bytes per scanline of glyph */ | |
100 | int nbyPadGlyph; /* server padded line of glyph */ | |
101 | ||
102 | ChangeGCVal gcvals[3]; | |
103 | ||
104 | if (pGC->miTranslate) { | |
105 | x += pDrawable->x; | |
106 | y += pDrawable->y; | |
107 | } | |
108 | ||
109 | pfont = pGC->font; | |
110 | width = FONTMAXBOUNDS(pfont, rightSideBearing) - | |
111 | FONTMINBOUNDS(pfont, leftSideBearing); | |
112 | height = FONTMAXBOUNDS(pfont, ascent) + FONTMAXBOUNDS(pfont, descent); | |
113 | ||
114 | pPixmap = (*pDrawable->pScreen->CreatePixmap) (pDrawable->pScreen, | |
115 | width, height, 1, | |
116 | CREATE_PIXMAP_USAGE_SCRATCH); | |
117 | if (!pPixmap) | |
118 | return; | |
119 | ||
120 | pGCtmp = GetScratchGC(1, pDrawable->pScreen); | |
121 | if (!pGCtmp) { | |
122 | (*pDrawable->pScreen->DestroyPixmap) (pPixmap); | |
123 | return; | |
124 | } | |
125 | ||
126 | gcvals[0].val = GXcopy; | |
127 | gcvals[1].val = 1; | |
128 | gcvals[2].val = 0; | |
129 | ||
130 | ChangeGC(NullClient, pGCtmp, GCFunction | GCForeground | GCBackground, | |
131 | gcvals); | |
132 | ||
133 | nbyLine = BitmapBytePad(width); | |
134 | pbits = malloc(height * nbyLine); | |
135 | if (!pbits) { | |
136 | (*pDrawable->pScreen->DestroyPixmap) (pPixmap); | |
137 | FreeScratchGC(pGCtmp); | |
138 | return; | |
139 | } | |
140 | while (nglyph--) { | |
141 | pci = *ppci++; | |
142 | pglyph = FONTGLYPHBITS(pglyphBase, pci); | |
143 | gWidth = GLYPHWIDTHPIXELS(pci); | |
144 | gHeight = GLYPHHEIGHTPIXELS(pci); | |
145 | if (gWidth && gHeight) { | |
146 | nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci); | |
147 | nbyPadGlyph = BitmapBytePad(gWidth); | |
148 | ||
149 | if (nbyGlyphWidth == nbyPadGlyph | |
150 | #if GLYPHPADBYTES != 4 | |
151 | && (((int) pglyph) & 3) == 0 | |
152 | #endif | |
153 | ) { | |
154 | pb = pglyph; | |
155 | } | |
156 | else { | |
157 | for (i = 0, pb = pbits; i < gHeight; | |
158 | i++, pb = pbits + (i * nbyPadGlyph)) | |
159 | for (j = 0; j < nbyGlyphWidth; j++) | |
160 | *pb++ = *pglyph++; | |
161 | pb = pbits; | |
162 | } | |
163 | ||
164 | if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber)) | |
165 | ValidateGC((DrawablePtr) pPixmap, pGCtmp); | |
166 | (*pGCtmp->ops->PutImage) ((DrawablePtr) pPixmap, pGCtmp, | |
167 | pPixmap->drawable.depth, | |
168 | 0, 0, gWidth, gHeight, | |
169 | 0, XYBitmap, (char *) pb); | |
170 | ||
171 | (*pGC->ops->PushPixels) (pGC, pPixmap, pDrawable, | |
172 | gWidth, gHeight, | |
173 | x + pci->metrics.leftSideBearing, | |
174 | y - pci->metrics.ascent); | |
175 | } | |
176 | x += pci->metrics.characterWidth; | |
177 | } | |
178 | (*pDrawable->pScreen->DestroyPixmap) (pPixmap); | |
179 | free(pbits); | |
180 | FreeScratchGC(pGCtmp); | |
181 | } | |
182 | ||
183 | void | |
184 | miImageGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, /* array of character info */ | |
185 | pointer pglyphBase /* start of array of glyphs */ | |
186 | ) | |
187 | { | |
188 | ExtentInfoRec info; /* used by QueryGlyphExtents() */ | |
189 | ChangeGCVal gcvals[3]; | |
190 | int oldAlu, oldFS; | |
191 | unsigned long oldFG; | |
192 | xRectangle backrect; | |
193 | ||
194 | QueryGlyphExtents(pGC->font, ppci, (unsigned long) nglyph, &info); | |
195 | ||
196 | if (info.overallWidth >= 0) { | |
197 | backrect.x = x; | |
198 | backrect.width = info.overallWidth; | |
199 | } | |
200 | else { | |
201 | backrect.x = x + info.overallWidth; | |
202 | backrect.width = -info.overallWidth; | |
203 | } | |
204 | backrect.y = y - FONTASCENT(pGC->font); | |
205 | backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); | |
206 | ||
207 | oldAlu = pGC->alu; | |
208 | oldFG = pGC->fgPixel; | |
209 | oldFS = pGC->fillStyle; | |
210 | ||
211 | /* fill in the background */ | |
212 | gcvals[0].val = GXcopy; | |
213 | gcvals[1].val = pGC->bgPixel; | |
214 | gcvals[2].val = FillSolid; | |
215 | ChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFillStyle, gcvals); | |
216 | ValidateGC(pDrawable, pGC); | |
217 | (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &backrect); | |
218 | ||
219 | /* put down the glyphs */ | |
220 | gcvals[0].val = oldFG; | |
221 | ChangeGC(NullClient, pGC, GCForeground, gcvals); | |
222 | ValidateGC(pDrawable, pGC); | |
223 | (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); | |
224 | ||
225 | /* put all the toys away when done playing */ | |
226 | gcvals[0].val = oldAlu; | |
227 | gcvals[1].val = oldFG; | |
228 | gcvals[2].val = oldFS; | |
229 | ChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFillStyle, gcvals); | |
230 | ValidateGC(pDrawable, pGC); | |
231 | ||
232 | } |