void CorrectUnscaledOutline(fnt_LocalGraphicStateType* gs) { fnt_ElementType* elem = gs->elements[GLYPHELEMENT]; IfDebugMessage(gs->unscaledOutlineIsWrong == false, "CorrectUnscaledOutline improperly called", 0); if (elem->pointCount) { F26Dot6 *x, *y; FWord *oox, *ooy, *ooStopX; Fixed scaleX, scaleY; scaleX = FixedDivide(fixed1, gs->globalGS->upemScale.x); scaleY = FixedDivide(fixed1, gs->globalGS->upemScale.y); x = elem->ox; // fix for bug #4177514 - IUP - unhinted outlines - not hinted outline y = elem->oy; oox = elem->oox; ooy = elem->ooy; ooStopX = oox + elem->pointCount; do { *oox++ = FixedMultiply(*x++, scaleX); *ooy++ = FixedMultiply(*y++, scaleY); } while (oox < ooStopX); } gs->unscaledOutlineIsWrong = false; }
F26Dot6 fnt_GetCVTEntrySlow(register fnt_LocalGraphicStateType *gs, ArrayIndex n) { register fixed scale; CHECK_CVT_READ( gs, n ); scale = fnt_GetCVTScale( gs ); return ( FixedMultiply( gs->globalGS->controlValueTable[ n ], scale ) ); }
F26Dot6 fnt_GetCVTEntrySlow(register fnt_LocalGraphicStateType *gs, ArrayIndex n) { register fixed scale; if (IS_BAD_CVT_INDEX(gs, n)) { FatalInterpreterError(gs, interp_font_program_error); } scale = fnt_GetCVTScale( gs ); return ( FixedMultiply( gs->globalGS->controlValueTable[ n ], scale ) ); }
/* * Executes the gxFont instructions. * This is the external interface to the interpreter. * * Parameter Description * * elements points to the character elements. Element 0 is always * reserved and not used by the actual character. * * ptr points at the first instruction. * eptr points to right after the last instruction * * globalGS points at the global graphics state * * TraceFunc is pointer to a callback functioned called with a pointer to the * local graphics state if TraceFunc is not null. * * Note: The stuff globalGS is pointing at must remain intact * between calls to this function. */ void fnt_Execute(fnt_ElementType* elements[], fnt_GlobalGraphicStateType *globalGS, tt_uint8 *ptr, register tt_uint8 *eptr, voidFunc TraceFunc, memoryContext* context, boolean hasStyleCoord, boolean hasVariantCVT, boolean hintingACompositGlyph) { fnt_LocalGraphicStateType GS; register fnt_LocalGraphicStateType *gs; /* the local graphics state pointer */ /* #pragma unused (TraceFunc,hasStyleCoord,hasVariantCVT) */ gs = &GS; gs->globalGS = globalGS; gs->elements = elements; gs->Pt0 = gs->Pt1 = gs->Pt2 = 0; gs->CE0 = gs->CE1 = gs->CE2 = elements[GLYPHELEMENT]; gs->free.x = gs->proj.x = gs->oldProj.x = shortFrac1; gs->free.y = gs->proj.y = gs->oldProj.y = 0; gs->pfProj = shortFrac1; gs->MovePoint = (FntMoveFunc) fnt_XMovePoint; gs->Project = (FntProjFunc) fnt_XProject; gs->OldProject = (FntProjFunc) fnt_XProject; gs->loop = 0; /* 1 less than count for faster loops. mrr */ #ifdef support_fake_variation_cvt gs->fakeVariantCVT = hasStyleCoord && !hasVariantCVT; #endif #ifdef debugging gs->valid_pfProj = true; IfDebugMessage(globalGS->pgmIndex != noProgramIndex && globalGS->pgmIndex != preProgramIndex && globalGS->pgmIndex != fontProgramIndex, "bad pgmIndex", globalGS->pgmIndex); #endif gs->projectionVectorIsNormal = false; gs->unscaledOutlineIsWrong = hintingACompositGlyph; if (globalGS->pgmIndex == fontProgramIndex) { #ifdef debugging gs->GetCVTEntry = (F26Dot6 (*) (struct fnt_LocalGraphicStateType *, ArrayIndex)) fnt_NilFunction; gs->GetSingleWidth = (F26Dot6 (*) (struct fnt_LocalGraphicStateType *)) fnt_NilFunction2; #endif goto ASSIGN_POINTERS; } #ifdef check_cvt_access_direction if (globalGS->pgmIndex == noProgramIndex) { char* flags = globalGS->cvtFlags; char* stop = flags + globalGS->cvtCount; while (flags < stop) *flags++ &= ~kCvtWrittenToByThisGlyph; } #endif if (globalGS->identityTransformation) { gs->GetCVTEntry = fnt_GetCVTEntryFast; gs->GetSingleWidth = fnt_GetSingleWidthFast; } else { gs->GetCVTEntry = fnt_GetCVTEntrySlow; gs->GetSingleWidth = fnt_GetSingleWidthSlow; } if (globalGS->localParBlock.sW) globalGS->localParBlock.scaledSW = FixedMultiply(globalGS->upemScale.x, globalGS->localParBlock.sW); ASSIGN_POINTERS: /* MTE: use the pre-allocated stack */ gs->stackPointer = gs->stackBase = globalGS->stackZone; gs->stackEnd = (F26Dot6*) ( ( (Ptr) globalGS->stackZone)+ globalGS->stackSize); gs->stackSize = globalGS->stackSize; gs->context = context; if (setjmp(gs->env) != 0) { ResetHintedOutline(elements[GLYPHELEMENT]); goto CLEAN_UP; } gs->TraceFunc = 0L; gs->Interpreter = (InterpreterFunc) fnt_InnerExecute ; gs->Interpreter( gs, ptr, eptr ); CLEAN_UP: { /* MTE */ if (gs->stackBase != nil /* MTE :not needed && context->callbacks->ScalerFunction == nil*/ ) { IfDebugMessage(gs->stackBase != gs->stackPointer, "leftover stack elements", gs->stackPointer - gs->stackBase); /* MTE not needed ScalerDisposeBlock(context, gs->stackBase, scalerScratchBlock);*/ } } }
F26Dot6 fnt_GetSingleWidthSlow(register fnt_LocalGraphicStateType *gs) { return ( FixedMultiply( gs->globalGS->localParBlock.scaledSW, fnt_GetCVTScale( gs ) ) ); }
BOOL FAR PASCAL DibTransparentStretch( PDIB pdibDst, LPVOID lpDst, int DstX, int DstY, int DstXE, int DstYE, PDIB pdibSrc, LPVOID lpSrc, int SrcX, int SrcY, int SrcXE, int SrcYE, char unsigned Transparent) { int XMax, YMax; Fixed fClipRatio; int iTemp; assert(pdibDst && lpDst); assert(pdibSrc && lpSrc); //*** Currently, this only works with 8-bit dibs assert(pdibDst->biBitCount == 8); assert(pdibSrc->biBitCount == 8); //*** This does NOT mirror assert (DstXE >= 0 && DstYE >= 0); assert (SrcXE >= 0 && SrcYE >= 0); XMax = (int)pdibDst->biWidth - 1; // [email protected]: I changed the following line. // In the version I was given, the abs was not here. // As a result, this did not handle top-down DIBS. // The rest of the routine works fine. YMax = abs((int)pdibDst->biHeight) - 1; ///End WWW Change. //*** Trivial reject if (DstX > XMax || DstY > YMax || (DstX + DstXE) < 0 || (DstY + DstYE) < 0) return TRUE; /// [email protected]: I duplicated the following line // of code. This is changing the starting position // of the blit from a 'standard' Windows top-down // coordinate system to a 'standard' DIB bottom-up // coordinate system. Unfortunately, the original // source only changed the destination. This meant // that it painted from the wrong spot in the source // DIB. So, I changed the source Y spot as well. DstY = YMax + 1 - DstY - DstYE; SrcY = abs ((int)pdibSrc->biHeight) - SrcY - SrcYE; //*** Clip the left edge if (DstX < 0) { fClipRatio = FixedDivide( IntToFixed(-DstX), IntToFixed(DstXE) ); //*** Remember, DstX is negative! DstXE = DstXE + DstX; DstX = 0; iTemp = FixedToInt( FixedMultiply( fClipRatio, IntToFixed(SrcXE) ) ); SrcX = SrcX + iTemp; SrcXE = SrcXE - iTemp; } //*** Clip the top edge if (DstY < 0) { fClipRatio = FixedDivide( IntToFixed(-DstY), IntToFixed(DstYE) ); //*** Remember, DstY is negative! DstYE = DstYE + DstY; DstY = 0; iTemp = FixedToInt( FixedMultiply( fClipRatio, IntToFixed(SrcYE) ) ); SrcY = SrcY + iTemp; SrcYE = SrcYE - iTemp; } // // [email protected] // XMax (and later YMax) are being used as 0 based when // they are in fact the width (and height) in pixels of // the dib and are 1 based. // //*** Clip the X extent if ((DstX + DstXE) > (XMax + 1)) { fClipRatio = FixedDivide( IntToFixed(XMax - DstX), IntToFixed(DstXE) ); DstXE = XMax - DstX + 1; SrcXE = FixedToInt( FixedMultiply(fClipRatio, IntToFixed(SrcXE)) ); //*** Make sure the round-off is correct if ((DstX + DstXE) < XMax) ++DstXE; } // // [email protected] // As above, YMax was being used as a 0 based value // instead of the 1 based that it is. // //*** Clip the Y extent if ((DstY + DstYE) > (YMax + 1)) { fClipRatio = FixedDivide( IntToFixed(YMax - DstY), IntToFixed(DstYE) ); DstYE = YMax - DstY + 1; SrcYE = FixedToInt( FixedMultiply(fClipRatio, IntToFixed(SrcYE)) ); //*** Make sure the round-off is correct if ((DstY + DstYE) < YMax) ++DstYE; } DoDibTransparentStretch( pdibDst, lpDst, DstX, DstY, DstXE, DstYE, pdibSrc, lpSrc, SrcX, SrcY, SrcXE, SrcYE, Transparent); return TRUE; }