void CBaselinePositions::Init( const scMuPoint& org, MicroPoint vjOffset, TypeSpec spec, const scFlowDir& fd ) { scAssert( spec != 0 ); MicroPoint ptsize = scCachedStyle::GetCachedStyle( spec ).GetPtSize(); if ( fd.IsHorizontal() ) { fTop = org.y - scRoundMP( (REAL)ptsize * RLU_BASEfmTop / scBaseRLUsystem ); fMiddle = org.y - scRoundMP( (REAL)ptsize * ( RLU_BASEfmTop - (scBaseRLUsystem/2)) / scBaseRLUsystem ); fRoman = org.y; fBottom = org.y + scRoundMP( (REAL)ptsize * RLU_BASEfmBottom / scBaseRLUsystem ); fTop += vjOffset; fMiddle += vjOffset; fRoman += vjOffset; fBottom += vjOffset; } else { fLeft = org.x - ptsize / 2; fMiddle = org.x; fRight = org.x + ptsize / 2; fLeft -= vjOffset; fMiddle -= vjOffset; fRight -= vjOffset; } }
/* ==================================================================== */ void scDrawLine::SetCharData( GlyphSize ptsize, GlyphSize setsize, const scFlowDir& fd, eFntBaseline baseline ) { fGlyphInfo.fontname = scCachedStyle::GetCurrentCache().GetFont(); fGlyphInfo.emphasis_ = scCachedStyle::GetCurrentCache().GetEmphasis(); fGlyphInfo.fontRender = scCachedStyle::GetCurrentCache().GetRender(); fGlyphInfo.typespec = scCachedStyle::GetCurrentCache().GetSpec(); fGlyphInfo.color = scCachedStyle::GetCurrentCache().GetColor(); fGlyphInfo.pointsize = ptsize; fGlyphInfo.setsize = setsize; fGlyphInfo.oblique = 0; fGlyphInfo.rotation = 0; fGlyphInfo.flowDir = fd; if ( fFlowDir.IsVertical() ) { fGlyphInfo.fBaseline = baseline; fBaseline.Set( scCachedStyle::GetCurrentCache().GetBaseline(), 0 ); } else { fGlyphInfo.fBaseline = baseline; fBaseline.Set( 0, -scCachedStyle::GetCurrentCache().GetBaseline() ); } }
/* ==================================================================== */ inline void scDrawLine::SetCharArray( const CharRecord& ch, BOOL addLSP ) { fChA->fGlyphID = ch.character; #ifdef _RUBI_SUPPORT fChA->flags = ch.flags; #endif if ( fFlowDir.IsVertical() ) { fChA->hEscapement = 0; fChA->vEscapement = ch.escapement; if ( addLSP ) fChA->vEscapement += fLetterSpace; } else { fChA->hEscapement = ch.escapement; if ( addLSP ) fChA->hEscapement += fLetterSpace; fChA->vEscapement = 0; } fCurPos.Translate( fChA->hEscapement, fChA->vEscapement ); IncrementDrawing(); }
/* ==================================================================== */ void scDrawLine::SetCaseCharData( caseState cs ) { OutputLine(); fGlyphInfo.fontname = scCachedStyle::GetCurrentCache().GetFont(); fGlyphInfo.emphasis_ = scCachedStyle::GetCurrentCache().GetEmphasis(); fGlyphInfo.fontRender = scCachedStyle::GetCurrentCache().GetRender(); fGlyphInfo.typespec = scCachedStyle::GetCurrentCache().GetSpec(); fGlyphInfo.color = scCachedStyle::GetCurrentCache().GetColor( ); if ( cs == lowerCase ) { fGlyphInfo.pointsize = scRoundGS( scCachedStyle::GetCurrentCache().GetGlyphHeight() * kSmallCapCorrection ); fGlyphInfo.setsize = scRoundGS( scCachedStyle::GetCurrentCache().GetGlyphWidth() * kSmallCapCorrection ); } else { fGlyphInfo.pointsize = scCachedStyle::GetCurrentCache().GetGlyphHeight(); fGlyphInfo.setsize = scCachedStyle::GetCurrentCache().GetGlyphWidth(); } fGlyphInfo.oblique = 0; fGlyphInfo.rotation = 0; fGlyphInfo.flowDir = fFlowDir; if ( fFlowDir.IsVertical() ) { fGlyphInfo.fBaseline = scCachedStyle::GetCurrentCache().GetVertBaseline( ); fBaseline.Set( scCachedStyle::GetCurrentCache().GetBaseline(), 0 ); } else { fGlyphInfo.fBaseline = scCachedStyle::GetCurrentCache().GetHorzBaseline( ); fBaseline.Set( 0, -scCachedStyle::GetCurrentCache().GetBaseline() ); } }
/* ==================================================================== */ void scDrawLine::ComputeTabInfo( scTabInfo& tabInfo) { if ( fFlowDir.IsVertical() ) TSTabInfo( pspec_, fSpec, tabInfo, fCurPos.y, 0L, 0L ); else TSTabInfo( pspec_, fSpec, tabInfo, fCurPos.x, 0L, 0L ); }
/* ==================================================================== */ void scDrawLine::ProcessRenMoji() { scRenMojiStr rm; CharRecord fauxChar; unsigned i; unsigned numChars = fChRec->flags.GetRenMoji(); // save spec rm.fSpec = fSpec; scAssert( numChars < 7 ); // process characters for ( i = 0; i < numChars; i++ ) { rm.fRenMojiStr[i] = *fChRec; rm.fRenMojiStr[i+1].character = 0; IncrementBackingStore(); } fauxChar.Set( emSpace, (fChRec-1)->escapement ); SetCharArray( fauxChar, false ); rm.fPosition = fCurPos; if ( fFlowDir.IsHorizontal() ) { switch ( scCachedStyle::GetCachedStyle().GetHorzBaseline() ) { case kTopBaseline: rm.fPosition.y = fBaselinePositions.fTop; break; case kMiddleBaseline: rm.fPosition.y = fBaselinePositions.fMiddle; break; case kBottomBaseline: rm.fPosition.y = fBaselinePositions.fBottom; break; default: case kRomanBaseline: rm.fPosition.y = fBaselinePositions.fRoman; break; } } else { switch ( scCachedStyle::GetCachedStyle().GetVertBaseline() ) { case kLeftBaseline: rm.fPosition.x = fBaselinePositions.fLeft; break; default: case kCenterBaseline: rm.fPosition.x = fBaselinePositions.fMiddle; break; case kRightBaseline: rm.fPosition.x = fBaselinePositions.fRight; break; } } fRenMojiArray.AppendData( (ElementPtr)&rm ); }
// process a hyphen at the end of a line if found void scDrawLine::ProcessHyphen( scCharFlags flags ) { if ( flags.IsKernPresent() ) { if ( fFlowDir.IsVertical() ) (fChA-1)->vEscapement = scCachedStyle::GetCurrentCache().GetEscapement( (fChRec-1)->character ) + fLetterSpace; else (fChA-1)->hEscapement = scCachedStyle::GetCurrentCache().GetEscapement( (fChRec-1)->character ) + fLetterSpace; } fChA->fGlyphID = scCachedStyle::GetCurrentCache().GetHyphChar(); if ( fFlowDir.IsVertical() ) { fChA->vEscapement = scCachedStyle::GetCurrentCache().GetEscapement( '-' ); fChA->hEscapement = 0; } else { fChA->hEscapement = scCachedStyle::GetCurrentCache().GetEscapement( '-' ); fChA->vEscapement = 0; } fCount++; }
// set the ComputedCharData structure void scDrawLine::SetRubiCharData( const scRubiData& rd, const scFlowDir& fd, eTSJustTypes rubiJust, int count, MicroPoint& letterspace ) { REAL rubifactor = ( (REAL)TSRubiSizeFactor( rd.fRubiSpec ) ) / 10000; fGlyphInfo.fontname = TSRubiFont( rd.fRubiSpec ); fGlyphInfo.emphasis_ = scCachedStyle::GetCurrentCache().GetEmphasis(); fGlyphInfo.fontRender = scCachedStyle::GetCurrentCache().GetFontRender(); fGlyphInfo.typespec = scCachedStyle::GetCurrentCache().GetSpec(); fGlyphInfo.color = TSRubiColor( rd.fRubiSpec ); fGlyphInfo.pointsize = ROUND( scCachedStyle::GetCurrentCache().GetPtSize() * rubifactor ); fGlyphInfo.setsize = ROUND( scCachedStyle::GetCurrentCache().GetSetSize() * rubifactor ); if ( fd.IsHorizontal() ) fGlyphInfo.fBaseline = kRomanBaseline; else fGlyphInfo.fBaseline = kLeftBaseline; if ( rubiJust & lastLineJust && count > 1 ) { letterspace = rd.fLetterSpace * ( count - 1 ); if ( fd.IsHorizontal() ) { fGlyphInfo.setsize += ( letterspace / count ); letterspace = 0; } else { fGlyphInfo.pointsize += ( letterspace / count ); letterspace = 0; } } else letterspace = rd.fLetterSpace; fGlyphInfo.oblique = 0; fGlyphInfo.rotation = 0; fGlyphInfo.flowDir = fFlowDir; }
/* ==================================================================== */ void scDrawLine::ComputeFillCharInfo( scTabInfo& tabInfo ) { scMuPoint pt( fCurPos ); if ( fFlowDir.IsVertical() ) TSfillCharInfo( fSpec, tabInfo.fillChar, tabInfo.fillCharAlign, pt.y, pt.x, fLineCount ); else TSfillCharInfo( fSpec, tabInfo.fillChar, tabInfo.fillCharAlign, pt.x, pt.y, fLineCount ); }
static Bool CheckPositionAndMark( scContUnit* para, /* the para we just reformatted */ scContUnit* nextPara, const scFlowDir& fd ) /* the next para we may have to rebreak */ { scTextline* lastTxl; /* last line of paraH */ scTextline* nextTxl; /* first line of nextParaH */ MicroPoint nextBaseln; /* 'ideal' baseline of nextTxlH */ if ( nextPara ) { if ( !nextPara->Marked( scREBREAK ) ) { lastTxl = para->GetLastline(); if ( lastTxl ) { nextTxl = LNNext( lastTxl ); if ( nextTxl ) { // determine what the baseline should be scLEADRefData ld; MicroPoint paraLead = lastTxl->ParaLead( ld, fd ); if ( !fd.IsVertical() ) nextBaseln = lastTxl->GetBaseline() + paraLead; else nextBaseln = lastTxl->GetBaseline() - paraLead; // compare it with reality and mark it if it is not correct if ( nextBaseln != nextTxl->GetBaseline() || nextTxl->GetPara() != nextPara ) nextPara->Mark( scREBREAK ); } else if ( !nextTxl ) /* no line - so mark rebreak */ nextPara->Mark( scREBREAK ); } } else if ( !para->GetLastline() ) { // if there is no last line we should unmark this para nextPara->Unmark( scREBREAK ); return false; } } return true; }
// this determines the leading plus paragraph space between this - the // last line of a paragraph - and the next paragraph MicroPoint scTextline::ParaLead( scLEADRefData& lead, const scFlowDir& fd ) { TypeSpec prevLeadSpec, curLeadSpec; MicroPoint spaceAbove, spaceBelow; MicroPoint paraspace; scLEADRefData topPara; scLEADRefData belowPara; scContUnit* nextPara; nextPara = GetPara()->GetNext(); if ( !nextPara ) return 0; MaxLead( prevLeadSpec ); curLeadSpec = nextPara->SpecAtStart(); if ( fd.IsHorizontal() ) { spaceBelow = scCachedStyle::GetCachedStyle( prevLeadSpec ).GetPtSize(); spaceAbove = scCachedStyle::GetCachedStyle( curLeadSpec ).GetPtSize(); } else { spaceBelow = scCachedStyle::GetCachedStyle( prevLeadSpec ).GetSetSize(); spaceAbove = scCachedStyle::GetCachedStyle( curLeadSpec ).GetSetSize(); } topPara.Set( spaceBelow, fd ); belowPara.Set( spaceAbove, fd ); paraspace = scCachedStyle::GetParaSpace( GetPara(), nextPara ); lead.SetBelowLead( topPara.GetBelowLead() ); lead.SetAboveLead( belowPara.GetAboveLead() ); lead.SetExternalSpace( paraspace ); return lead.GetLead(); }
void scLEADRefData::ComputeAboveBelow( MicroPoint lead, const scFlowDir& fd ) { if ( fd.IsHorizontal() ) { static REAL realAbove = (REAL)RLU_BASEfmTop / scBaseRLUsystem; static REAL realBelow = (REAL)RLU_BASEfmBottom / scBaseRLUsystem; static MicroPoint lastlead; static MicroPoint abovelead; static MicroPoint belowlead; if ( lastlead != lead ) { abovelead = scRoundMP( realAbove * lead ); belowlead = scRoundMP( realBelow * lead ); lastlead = lead; } fAboveLead = abovelead; fBelowLead = belowlead; } else { fAboveLead = lead / 2; fBelowLead = lead / 2; } }
void scDrawLine::SetCharData( ) { fGlyphInfo.fontname = scCachedStyle::GetCurrentCache().GetFont(); fGlyphInfo.emphasis_ = scCachedStyle::GetCurrentCache().GetEmphasis(); fGlyphInfo.fontRender = scCachedStyle::GetCurrentCache().GetRender(); fGlyphInfo.typespec = scCachedStyle::GetCurrentCache().GetSpec(); fGlyphInfo.color = scCachedStyle::GetCurrentCache().GetColor( ); fGlyphInfo.pointsize = scCachedStyle::GetCurrentCache().GetGlyphHeight(); fGlyphInfo.setsize = scCachedStyle::GetCurrentCache().GetGlyphWidth(); fGlyphInfo.oblique = 0; fGlyphInfo.rotation = 0; fGlyphInfo.flowDir = fFlowDir; if ( fFlowDir.IsVertical() ) { fGlyphInfo.fBaseline = scCachedStyle::GetCurrentCache().GetVertBaseline( ); fBaseline.Set( scCachedStyle::GetCurrentCache().GetBaseline(), 0 ); } else { fGlyphInfo.fBaseline = scCachedStyle::GetCurrentCache().GetHorzBaseline( ); fBaseline.Set( 0, -scCachedStyle::GetCurrentCache().GetBaseline() ); } }
/* ==================================================================== */ void scDrawLine::DrawRenMoji() { int i, j; scRenMojiStr rm; MicroPoint microMeasure; MicroPoint romanBaselineShift; MicroPoint maxMeasure; REAL ptsizeAdjust; REAL setwidthAdjust; scFlowDir antiFlowDir; scFlowDir saveFlowDir( fFlowDir ); TypeSpec saveSpec = scCachedStyle::GetCurrentCache().GetSpec(); antiFlowDir.CounterFlow( fFlowDir ); for ( i = 0; i < fRenMojiArray.GetNumItems(); i++ ) { fRenMojiArray.GetDataAt( i, (ElementPtr)&rm ); scCachedStyle::SetFlowdir( antiFlowDir ); scCachedStyle::GetCachedStyle( rm.fSpec ); microMeasure = BRKComposeRenMoji( rm.fRenMojiStr, rm.fSpec, antiFlowDir, true ); maxMeasure = scCachedStyle::GetCurrentCache().GetPtSize() * 2; #ifdef kMakimotoRenMoji int doMakimotoRenMoji = 1; #else int doMakimotoRenMoji = 0; #endif if ( doMakimotoRenMoji && microMeasure > maxMeasure ) { // first try to reduce setwidth setwidthAdjust = (REAL)maxMeasure / microMeasure; if ( setwidthAdjust < 0.60 ) ptsizeAdjust = setwidthAdjust; // adjust pointsize to else ptsizeAdjust = 1.0; microMeasure = ROUND( microMeasure * setwidthAdjust ); for ( j = 0; rm.fRenMojiStr[j].character; j++ ) rm.fRenMojiStr[j].escapement = ROUND( rm.fRenMojiStr[j].escapement * setwidthAdjust ); } else { setwidthAdjust = 1.0; ptsizeAdjust = 1.0; } MicroPoint ptsize = ROUND( ptsizeAdjust * scCachedStyle::GetCurrentCache().GetPtSize() ); MicroPoint setsize = ROUND( setwidthAdjust * scCachedStyle::GetCurrentCache().GetSetSize() ); if ( fFlowDir.IsVertical() ) { MicroPoint midPoint, left; switch ( scCachedStyle::GetCachedStyle().GetVertBaseline() ) { case kLeftBaseline: midPoint = ROUND( scCachedStyle::GetCurrentCache().GetPtSize() * (scBaseRLUsystem/2) / scBaseRLUsystem ); break; case kCenterBaseline: midPoint = 0; break; case kRightBaseline: midPoint = ROUND( -scCachedStyle::GetCurrentCache().GetPtSize() * (scBaseRLUsystem/2) / scBaseRLUsystem ); break; } romanBaselineShift = -(scCachedStyle::GetCurrentCache().GetPtSize()/2) + (ptsize/2) - (ptsize*RLU_BASEfmBottom/scBaseRLUsystem); left = midPoint - microMeasure / 2; rm.fPosition.Translate( left, romanBaselineShift ); } else { MicroPoint midPoint, top; switch ( scCachedStyle::GetCachedStyle().GetHorzBaseline() ) { case kTopBaseline: midPoint = ROUND( scCachedStyle::GetCurrentCache().GetPtSize() * (scBaseRLUsystem/2) / scBaseRLUsystem ); break; case kMiddleBaseline: midPoint = 0; break; case kBottomBaseline: midPoint = ROUND( -scCachedStyle::GetCurrentCache().GetPtSize() * (scBaseRLUsystem/2) / scBaseRLUsystem ); break; case kRomanBaseline: midPoint = ROUND(-scCachedStyle::GetCurrentCache().GetPtSize() * (scBaseRLUsystem/2-RLU_BASEfmBottom) / scBaseRLUsystem); break; } top = midPoint - microMeasure/2; rm.fPosition.Translate( -scCachedStyle::GetCurrentCache().GetSetSize() / 2, top ); } fDrawOrigin = rm.fPosition; fFlowDir = antiFlowDir; ptsize = ROUND( ptsizeAdjust * scCachedStyle::GetCurrentCache().GetPtSize() ); setsize = ROUND( setwidthAdjust * scCachedStyle::GetCurrentCache().GetSetSize() ); if ( fFlowDir.IsHorizontal() ) SetCharData( ptsize, setsize, antiFlowDir, kRomanBaseline ); else SetCharData( setsize, ptsize, antiFlowDir, kCenterBaseline ); for ( j = 0; rm.fRenMojiStr[j].character; j++ ) SetCharArray( rm.fRenMojiStr[j], true ); OutputLine(); fFlowDir = saveFlowDir; } scCachedStyle::SetFlowdir( saveFlowDir ); scCachedStyle::GetCachedStyle( saveSpec ); }
// draw japanese rubi void scDrawLine::DrawRubi( const scRubiData& rd ) { int i, count = CharacterBufLen( rd.fCh ); MicroPoint hEscapement; MicroPoint vEscapement; scXRect xrect( rd.fExtents ); scMuPoint org = rd.fOrg; scMuPoint trans; TSJust rubiJust = TSRubiJust( rd.fRubiSpec ); MicroPoint letterspace; scCachedStyle::GetCachedStyle( rd.fRubiSpec ); SetRubiCharData( rd, fFlowDir, rubiJust, count, letterspace ); trans = fOrigin; if ( fFlowDir.IsHorizontal() ) { switch ( scCachedStyle::GetCachedStyle().GetHorzBaseline() ) { case kTopBaseline: trans.y = fBaselinePositions.fTop; break; case kMiddleBaseline: trans.y = fBaselinePositions.fMiddle; break; case kBottomBaseline: trans.y = fBaselinePositions.fBottom; break; default: case kRomanBaseline: trans.y = fBaselinePositions.fRoman; break; } } else { switch ( scCachedStyle::GetCachedStyle().GetVertBaseline() ) { case kLeftBaseline: trans.x = fBaselinePositions.fLeft; break; default: case kCenterBaseline: trans.x = fBaselinePositions.fMiddle; break; case kRightBaseline: trans.x = fBaselinePositions.fRight; break; } } org.Translate( trans ); fCurPos = org; if ( fFlowDir.IsVertical() ) { hEscapement = 0; vEscapement = fGlyphInfo.pointsize + letterspace; } else { hEscapement = fGlyphInfo.setsize + letterspace; vEscapement = 0; } fChA = fChArray; for ( i = 0; i < count; i++ ) { fChA[i].ch = rd.fCh[i]; fChA[i].flags.ClearFlags(); fChA[i].hEscapement = hEscapement; fChA[i].vEscapement = vEscapement; } APPDrawStartLine( fDawContext, org.x, org.y, hrect ); APPDrawString( fDrawContext, fChArray, count, org.x, org.y, fGlyphInfo ); APPDrawEndLine( fDrawContext ); }
void scDrawLine::DrawTabSpace() { scTabInfo tabInfo; GlyphSize fillChWid; CharRecord chRec; if ( fChRec->character == scFillSpace ) ComputeFillCharInfo( tabInfo ); else ComputeTabInfo( tabInfo ); if ( fFlowDir.IsVertical() ) tabInfo.xPosition = fCurPos.y + fChRec->escapement; else tabInfo.xPosition = fCurPos.x + fChRec->escapement; fillChWid = scCachedStyle::GetCurrentCache().GetEscapement( tabInfo.fillChar ); if ( !GlyphAvail( tabInfo.fillChar ) || fChRec->escapement < 0 || fillChWid <= 0 ) { chRec.Set( CMctToAPP( fChRec->character ), fChRec->escapement ); SetCharArray( chRec, false ); } else { MicroPoint endX; GlyphSize headPad, tailPad; if ( fFlowDir.IsVertical() ) ComputeFillChar( tabInfo.fillCharAlign, fCurPos.y, tabInfo.xPosition, fLineCount, fillChWid, headPad, tailPad ); else ComputeFillChar( tabInfo.fillCharAlign, fCurPos.x, tabInfo.xPosition, fLineCount, fillChWid, headPad, tailPad ); endX = tabInfo.xPosition; // for show invisibles if ( CMctToAPP( scTabSpace ) ) { chRec.Set( CMctToAPP( scTabSpace ), 0 ); SetCharArray( chRec, false ); } if ( headPad ) { chRec.Set( CMctToAPP( scEmptySpace ), headPad ); SetCharArray( chRec, false ); } if ( fFlowDir.IsVertical() ) { while ( fCurPos.y + fillChWid <= ( endX - tailPad ) ) { chRec.Set( CMctToAPP( tabInfo.fillChar ), fillChWid ); SetCharArray( chRec, false ); } } else { while ( fCurPos.x + fillChWid <= ( endX - tailPad ) ) { chRec.Set( CMctToAPP( tabInfo.fillChar ), fillChWid ); SetCharArray( chRec, false ); } } if ( tailPad ) { chRec.Set( CMctToAPP( scEmptySpace ), tailPad ); SetCharArray( chRec, false ); } } }