miglyph.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. *
  3. * Copyright © 2000 SuSE, Inc.
  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, and that the name of SuSE not be used in advertising or
  10. * publicity pertaining to distribution of the software without specific,
  11. * written prior permission. SuSE makes no representations about the
  12. * suitability of this software for any purpose. It is provided "as is"
  13. * without express or implied warranty.
  14. *
  15. * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
  17. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  18. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  19. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  20. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21. *
  22. * Author: Keith Packard, SuSE, Inc.
  23. */
  24. #ifdef HAVE_DIX_CONFIG_H
  25. #include <dix-config.h>
  26. #endif
  27. #include "scrnintstr.h"
  28. #include "gcstruct.h"
  29. #include "pixmapstr.h"
  30. #include "windowstr.h"
  31. #include "mi.h"
  32. #include "picturestr.h"
  33. #include "mipict.h"
  34. Bool
  35. miRealizeGlyph(ScreenPtr pScreen, GlyphPtr glyph)
  36. {
  37. return TRUE;
  38. }
  39. void
  40. miUnrealizeGlyph(ScreenPtr pScreen, GlyphPtr glyph)
  41. {
  42. }
  43. _X_EXPORT void
  44. miGlyphExtents(int nlist, GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
  45. {
  46. int x1, x2, y1, y2;
  47. int n;
  48. GlyphPtr glyph;
  49. int x, y;
  50. x = 0;
  51. y = 0;
  52. extents->x1 = MAXSHORT;
  53. extents->x2 = MINSHORT;
  54. extents->y1 = MAXSHORT;
  55. extents->y2 = MINSHORT;
  56. while (nlist--) {
  57. x += list->xOff;
  58. y += list->yOff;
  59. n = list->len;
  60. list++;
  61. while (n--) {
  62. glyph = *glyphs++;
  63. x1 = x - glyph->info.x;
  64. if (x1 < MINSHORT)
  65. x1 = MINSHORT;
  66. y1 = y - glyph->info.y;
  67. if (y1 < MINSHORT)
  68. y1 = MINSHORT;
  69. x2 = x1 + glyph->info.width;
  70. if (x2 > MAXSHORT)
  71. x2 = MAXSHORT;
  72. y2 = y1 + glyph->info.height;
  73. if (y2 > MAXSHORT)
  74. y2 = MAXSHORT;
  75. if (x1 < extents->x1)
  76. extents->x1 = x1;
  77. if (x2 > extents->x2)
  78. extents->x2 = x2;
  79. if (y1 < extents->y1)
  80. extents->y1 = y1;
  81. if (y2 > extents->y2)
  82. extents->y2 = y2;
  83. x += glyph->info.xOff;
  84. y += glyph->info.yOff;
  85. }
  86. }
  87. }
  88. #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
  89. _X_EXPORT void
  90. miGlyphs(CARD8 op,
  91. PicturePtr pSrc,
  92. PicturePtr pDst,
  93. PictFormatPtr maskFormat,
  94. INT16 xSrc,
  95. INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
  96. {
  97. PixmapPtr pPixmap = 0;
  98. PicturePtr pPicture;
  99. PixmapPtr pMaskPixmap = 0;
  100. PicturePtr pMask;
  101. ScreenPtr pScreen = pDst->pDrawable->pScreen;
  102. int width = 0, height = 0;
  103. int x, y;
  104. int xDst = list->xOff, yDst = list->yOff;
  105. int n;
  106. GlyphPtr glyph;
  107. int error;
  108. BoxRec extents;
  109. CARD32 component_alpha;
  110. if (maskFormat) {
  111. GCPtr pGC;
  112. xRectangle rect;
  113. miGlyphExtents(nlist, list, glyphs, &extents);
  114. if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
  115. return;
  116. width = extents.x2 - extents.x1;
  117. height = extents.y2 - extents.y1;
  118. pMaskPixmap =
  119. (*pScreen->CreatePixmap) (pScreen, width, height,
  120. maskFormat->depth);
  121. if (!pMaskPixmap)
  122. return;
  123. component_alpha = NeedsComponent(maskFormat->format);
  124. pMask = CreatePicture(0, &pMaskPixmap->drawable,
  125. maskFormat, CPComponentAlpha, &component_alpha,
  126. serverClient, &error);
  127. if (!pMask) {
  128. (*pScreen->DestroyPixmap) (pMaskPixmap);
  129. return;
  130. }
  131. pGC = GetScratchGC(pMaskPixmap->drawable.depth, pScreen);
  132. ValidateGC(&pMaskPixmap->drawable, pGC);
  133. rect.x = 0;
  134. rect.y = 0;
  135. rect.width = width;
  136. rect.height = height;
  137. (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
  138. FreeScratchGC(pGC);
  139. x = -extents.x1;
  140. y = -extents.y1;
  141. }
  142. else {
  143. pMask = pDst;
  144. x = 0;
  145. y = 0;
  146. }
  147. pPicture = 0;
  148. while (nlist--) {
  149. x += list->xOff;
  150. y += list->yOff;
  151. n = list->len;
  152. while (n--) {
  153. glyph = *glyphs++;
  154. if (!pPicture) {
  155. pPixmap =
  156. GetScratchPixmapHeader(pScreen, glyph->info.width,
  157. glyph->info.height,
  158. list->format->depth,
  159. list->format->depth, 0,
  160. (pointer) (glyph + 1));
  161. if (!pPixmap)
  162. return;
  163. component_alpha = NeedsComponent(list->format->format);
  164. pPicture = CreatePicture(0, &pPixmap->drawable, list->format,
  165. CPComponentAlpha, &component_alpha,
  166. serverClient, &error);
  167. if (!pPicture) {
  168. FreeScratchPixmapHeader(pPixmap);
  169. return;
  170. }
  171. }
  172. (*pScreen->ModifyPixmapHeader) (pPixmap,
  173. glyph->info.width,
  174. glyph->info.height, 0, 0, -1,
  175. (pointer) (glyph + 1));
  176. pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  177. if (maskFormat) {
  178. CompositePicture(PictOpAdd,
  179. pPicture,
  180. None,
  181. pMask,
  182. 0, 0,
  183. 0, 0,
  184. x - glyph->info.x,
  185. y - glyph->info.y,
  186. glyph->info.width, glyph->info.height);
  187. }
  188. else {
  189. CompositePicture(op,
  190. pSrc,
  191. pPicture,
  192. pDst,
  193. xSrc + (x - glyph->info.x) - xDst,
  194. ySrc + (y - glyph->info.y) - yDst,
  195. 0, 0,
  196. x - glyph->info.x,
  197. y - glyph->info.y,
  198. glyph->info.width, glyph->info.height);
  199. }
  200. x += glyph->info.xOff;
  201. y += glyph->info.yOff;
  202. }
  203. list++;
  204. if (pPicture) {
  205. FreeScratchPixmapHeader(pPixmap);
  206. FreePicture((pointer) pPicture, 0);
  207. pPicture = 0;
  208. pPixmap = 0;
  209. }
  210. }
  211. if (maskFormat) {
  212. x = extents.x1;
  213. y = extents.y1;
  214. CompositePicture(op,
  215. pSrc,
  216. pMask,
  217. pDst,
  218. xSrc + x - xDst,
  219. ySrc + y - yDst, 0, 0, x, y, width, height);
  220. FreePicture((pointer) pMask, (XID) 0);
  221. (*pScreen->DestroyPixmap) (pMaskPixmap);
  222. }
  223. }