home *** CD-ROM | disk | FTP | other *** search
- /* graphics libraries:
- text library
- by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
- Copyright 1987 - 1991 Apple Computer, Inc. All rights reserved. */
-
-
- #include <Memory.h>
- #ifndef bold
- #include <Quickdraw.h>
- #endif
- #include "font routines.h"
- #include "graphics libraries.h"
- #include "layout routines.h"
-
-
- gxShape NewChar(const char data, const gxPoint *position)
- {
- return GXNewText(1, (const unsigned char *)&data, position);
- }
-
-
- void SetChar(gxShape target, const char data, const gxPoint *position)
- {
- GXSetText(target, 1, (const unsigned char *)&data, position);
- }
-
-
- void gDrawChar(const char data, const gxPoint *position)
- {
- GXDrawText(1, (const unsigned char *)&data, position);
- }
-
-
- gxShape NewCString(const char *cString, const gxPoint *position)
- {
- register long len = 0;
- register const char *find0 = cString;
-
- while (*find0++ != 0)
- ++len;
- return GXNewText(len, (unsigned char *)cString, position);
- }
-
-
- void SetCString(gxShape source, const char *cString, const gxPoint *position)
- {
- register long len = 0;
- register const char *find0 = cString;
-
- while (*find0++ != 0)
- ++len;
- GXSetText(source, len, (unsigned char *)cString, position);
- }
-
-
- Fixed FixTextWidth(register const unsigned char *ch, register short len)
- {
- gxPoint pt;
- gxShape textShape = GXNewText(len, ch, nil);
- Fixed width = GetShapeAdvance(textShape, &pt)->x;
-
- GXDisposeShape(textShape);
- return width;
- }
-
-
- Fixed FixCStringWidth(register const char *ch)
- {
- register long len = 0;
- register const char *find0 = ch;
-
- while (*find0++ != 0)
- ++len;
- return FixTextWidth((unsigned char *) ch, len);
- }
-
-
- gxShape NewPString(register const char *pString, register const gxPoint *position)
- {
- return GXNewText(*pString, (unsigned char *)pString + 1, position);
- }
-
-
- void SetPString(register gxShape source, register const char *pString, register const gxPoint *position)
- {
- GXSetText(source, *pString, (unsigned char *) pString + 1, position);
- }
-
-
- Fixed FixPStringWidth(register const char *ch)
- {
- return FixTextWidth((unsigned char *) ch + 1, *ch);
- }
-
-
- Fixed FixCharWidth(char ch)
- {
- return FixTextWidth((unsigned char *) &ch, 1);
- }
-
-
- void DrawCString(register const char *ch, register const gxPoint *position)
- {
- register long len = 0;
- register const char *find0 = ch;
-
- while (*find0++ != 0)
- ++len;
- GXDrawText(len, (unsigned char *)ch, position);
- }
-
-
- void DrawPString(register const char *ch, register const gxPoint *position)
- {
- GXDrawText(*ch, (unsigned char *)ch + 1, position);
- }
-
-
- void SetGlyphText(register gxShape source, register unsigned const char *text, long length)
- {
- GXSetGlyphs(source, length, text, nil, nil, nil, nil, nil);
- }
-
-
- void SetGlyphAdvance(register gxShape source, register const long advanceBits[])
- {
- GXSetGlyphs(source, 0, nil, nil, advanceBits, nil, nil, nil);
- }
-
-
- void SetGlyphStyles(register gxShape source, register const short styleRuns[], register const gxStyle glyphStyles[])
- {
- GXSetGlyphs(source, 0, nil, nil, nil, nil, styleRuns, glyphStyles);
- }
-
-
- long GetGlyphText(register gxShape source, register unsigned char *text)
- {
- return GXGetGlyphs(source, nil, text, nil, nil, nil, nil, nil, nil);
- }
-
-
- long GetGlyphAdvance(register gxShape source, register long advanceBits[])
- {
- long length;
-
- GXGetGlyphs(source, &length, nil, nil, advanceBits, nil, nil, nil, nil);
- return length;
- }
-
-
- long GetGlyphStyles(register gxShape source, register short styleRuns[], register gxStyle glyphStyles[])
- {
- long runs;
-
- GXGetGlyphs(source, nil, nil, nil, nil, nil, &runs, styleRuns, glyphStyles);
- return runs;
- }
-
- #define kBoldnessFactor 18
-
- static gxTextFace *SetCommonFace(register commonFace face)
- {
- register gxTextFace *newFace;
- register long faceLayers = 1;
- register gxFaceLayer *activeLayer;
- gxTransform italicTransform = nil;
- gxStyle nullStyle = nil;
- boolean doOutline = (face & outline) != 0;
- boolean doBold = (face & bold) != 0;
- boolean doShadow = (face & shadow) != 0;
- boolean doShadowOutline = (face & shadow+outline) != 0;
- Fixed standardBolding = fixed1/kBoldnessFactor;
- Fixed shadowBolding = ff(3)/(kBoldnessFactor*2);
- Fixed shadowTranslate = 2*standardBolding / 3;
-
- if (face == 0)
- return nil;
-
- {
- register long shadowOutlineLayers = doShadowOutline ? 2 : 0;
- register long underlineLayers = (face & underline) ? doShadowOutline + 2 : 0;
-
- faceLayers = shadowOutlineLayers + underlineLayers + (shadowOutlineLayers == 0);
- }
- if (face & italic) {
- italicTransform = GXNewTransform();
-
- GXSkewTransform(italicTransform, -fixed1/4, 0, 0, 0);
- }
- if (face & underline) {
- nullStyle = GXNewStyle();
- GXSetStyleTextSize(nullStyle, fixed1);
- GXSetStyleFont(nullStyle, 0);
- }
-
- newFace = (gxTextFace *) NewPtr(sizeof(gxTextFace) + (faceLayers - gxAnyNumber) * sizeof(gxFaceLayer));
- newFace->faceLayers = faceLayers;
- ResetMapping(&newFace->advanceMapping);
- if ( ((face & extend) != 0) ^ ((face & condense) != 0) )
- if (face & extend)
- ScaleMapping(&newFace->advanceMapping, ff(100)/85, fixed1, 0, 0);
- else
- ScaleMapping(&newFace->advanceMapping, ff(85)/100, fixed1, 0, 0);
-
- activeLayer = &newFace->faceLayer[0];
-
- if (doShadowOutline) {
- if (face & underline) {
- /*** doesn't discriminate between outline and shadow ***/
- activeLayer->outlineFill = gxNoFill;
- activeLayer->flags = gxUnderlineAdvanceLayer;
- activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
- activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
- GXMoveTransform(activeLayer->outlineTransform, 0, ff(2)/kBoldnessFactor);
- activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
- ++activeLayer;
-
- activeLayer->outlineFill = gxNoFill;
- activeLayer->flags = gxUnderlineAdvanceLayer;
- activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
- GXSetStylePen(activeLayer->outlineStyle, fixed1/8);
- activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
- GXMoveTransform(activeLayer->outlineTransform, 0, ff(2+doShadow)/kBoldnessFactor);
- activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
- ++activeLayer;
-
- activeLayer->outlineFill = gxNoFill;
- activeLayer->flags = gxUnderlineAdvanceLayer + gxWhiteLayer;
- activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
- GXSetStylePen(activeLayer->outlineStyle, fixed1/16);
- activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
- GXMoveTransform(activeLayer->outlineTransform, 0, ff(2+doShadow)/kBoldnessFactor);
- activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
- ++activeLayer;
- }
-
- activeLayer->outlineFill = gxWindingFill;
- activeLayer->flags = 0;
- activeLayer->outlineStyle = nil;
- activeLayer->boldOutset.x = (doShadow ? shadowBolding : standardBolding) + standardBolding*doBold;
- activeLayer->boldOutset.y = doShadow ? shadowBolding : standardBolding;
- if (doShadow) {
- activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
- GXMoveTransform(activeLayer->outlineTransform, shadowTranslate, shadowTranslate);
- } else
- activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
- ++activeLayer;
-
- activeLayer->outlineFill = gxWindingFill;
- activeLayer->flags = gxWhiteLayer;
- activeLayer->outlineStyle = nil;
- activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
- activeLayer->boldOutset.x = doBold*standardBolding;
- activeLayer->boldOutset.y = 0;
- } else {
- if (face & underline) {
- activeLayer->outlineFill = gxNoFill;
- activeLayer->flags = gxUnderlineAdvanceLayer;
- activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
- activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
- GXMoveTransform(activeLayer->outlineTransform, 0, ff(doBold+1)/kBoldnessFactor + shadowTranslate);
- activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
- ++activeLayer;
-
- activeLayer->outlineFill = gxNoFill;
- activeLayer->flags = gxUnderlineAdvanceLayer;
- activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
- GXSetStylePen(activeLayer->outlineStyle, fixed1/12);
- activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
- GXMoveTransform(activeLayer->outlineTransform, 0, ff(doBold+1)/kBoldnessFactor + shadowTranslate);
- activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
- ++activeLayer;
- }
-
- activeLayer->outlineFill = gxWindingFill;
- activeLayer->flags = 0;
- activeLayer->outlineStyle = nil;
- activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
- activeLayer->boldOutset.x = doBold * standardBolding;
- activeLayer->boldOutset.y = doBold * standardBolding;
- }
- if (activeLayer != &newFace->faceLayer[faceLayers-1])
- DebugStr((unsigned char *)"\pMiscalculated size of gxTextFace structure");
-
- if (italicTransform)
- GXDisposeTransform(italicTransform);
- if (nullStyle)
- GXDisposeStyle(nullStyle);
-
- return newFace;
- }
-
-
- static void DisposeFaceParts(gxTextFace *newFace)
- {
- long activeLayer = newFace->faceLayers - 1;
-
- do {
- if (newFace->faceLayer[activeLayer].outlineStyle)
- GXDisposeStyle(newFace->faceLayer[activeLayer].outlineStyle);
- if (newFace->faceLayer[activeLayer].outlineTransform)
- GXDisposeTransform(newFace->faceLayer[activeLayer].outlineTransform);
- } while (--activeLayer >= 0);
- DisposePtr((Ptr) newFace);
- }
-
-
- void SetStyleCommonFace(gxStyle source, commonFace face)
- {
- gxTextFace *newFace = SetCommonFace(face);
-
- GXSetStyleFace(source, newFace);
- if (newFace)
- DisposeFaceParts(newFace);
- }
-
-
- void SetShapeCommonFace(gxShape source, commonFace face)
- {
- gxTextFace *newFace = SetCommonFace(face);
-
- GXSetShapeFace(source, newFace);
- if (newFace)
- DisposeFaceParts(newFace);
- }
-
-
- commonFace GetStyleCommonFace(gxStyle source)
- {
- long layers = GXGetStyleFace(source, nil);
-
- if (layers == -1)
- return 0;
- { gxTextFace *realFacePtr = (gxTextFace *) NewPtr(sizeof(gxTextFace) + (layers - 1) * sizeof(gxFaceLayer));
- commonFace face = 0;
- long activeLayer = 0;
- gxStyle curStyle;
- gxTransform curTransform;
-
- GXGetStyleFace(source, realFacePtr);
- if (realFacePtr->faceLayers == 2) {
- face |= shadow;
- activeLayer++;
- }
- if (realFacePtr->faceLayer[activeLayer].outlineFill == gxClosedFrameFill)
- face |= outline;
- if (realFacePtr->faceLayer[activeLayer].flags & gxUnderlineAdvanceLayer)
- face |= underline;
- curStyle = realFacePtr->faceLayer[activeLayer].outlineStyle;
- if (curStyle)
- if (realFacePtr->faceLayer[activeLayer].boldOutset.x | realFacePtr->faceLayer[activeLayer].boldOutset.y)
- face |= bold;
- curTransform = realFacePtr->faceLayer[activeLayer].outlineTransform;
- if (curTransform)
- { gxMapping map;
-
- GXGetTransformMapping(curTransform, &map);
- if (map.map[0][0] >= IntToFixed(100) / 85)
- face |= extend;
- if (map.map[0][0] <= IntToFixed(85) / 100)
- face |= condense;
- if (map.map[1][0])
- face |= italic;
- }
- { gxFaceLayer *layer = realFacePtr->faceLayer;
-
- while (layers--) {
- DisposeStyleAt(&layer->outlineStyle);
- DisposeTransformAt(&layer->outlineTransform);
- layer++;
- }
- }
- return face;
- }
- }
-
-
- commonFace GetShapeCommonFace(gxShape source)
- {
- return GetStyleCommonFace(GXGetShapeStyle(source));
- }
-
- #define offsetField(type, field) ((long) &((type *) 0)->field)
-
- gxPoint *GetShapeAdvance(gxShape source, gxPoint *advancePt)
- {
- gxShapeType type = GXGetShapeType(source);
-
- switch (type) {
- case gxEmptyType:
- case gxFullType:
- #ifdef debugging
- GXPostGraphicsError(graphic_type_does_not_contain_points);
- #endif
- break;
- case gxPointType:
- case gxLineType:
- case gxCurveType:
- case gxRectangleType:
- case gxPolygonType:
- case gxPathType:
- case gxPictureType:
- { gxRectangle bounds;
-
- GXGetShapeBounds(source, 0, &bounds);
- advancePt->x = bounds.right - bounds.left;
- advancePt->y = bounds.bottom - bounds.top;
- }
- break;
- case gxTextType:
- case gxGlyphType:
- case gxLayoutType:
- { long characters;
- gxPoint *positions;
-
- if (type == gxTextType)
- GXGetText(source, &characters, nil, nil);
- else if (type == gxGlyphType)
- GXGetGlyphs(source, &characters, nil, nil, nil, nil, nil, nil, nil);
- else characters = GXGetLayoutGlyphs(source, nil, nil, nil, nil, nil, nil, nil);
- positions = (gxPoint *) NewPtr((characters + 1) * sizeof(gxPoint));
- GXGetGlyphMetrics(source, positions, nil, nil);
- advancePt->x = positions[characters].x - positions[0].x;
- advancePt->y = positions[characters].y - positions[0].y;
- DisposePtr((Ptr) positions);
- }
- break;
- }
- return advancePt;
- }
-