00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "precompiled_starmath.hxx"
00038
00039 #define APPEND(str,ascii) str.AppendAscii(RTL_CONSTASCII_STRINGPARAM(ascii))
00040
00041 #ifndef _SV_GEN_HXX //autogen
00042 #include <tools/gen.hxx>
00043 #endif
00044 #ifndef _FRACT_HXX //autogen
00045 #include <tools/fract.hxx>
00046 #endif
00047 #ifndef INCLUDED_RTL_MATH_HXX
00048 #include <rtl/math.hxx>
00049 #endif
00050 #ifndef _TOOLS_COLOR_HXX
00051 #include <tools/color.hxx>
00052 #endif
00053 #ifndef _SV_METRIC_HXX //autogen
00054 #include <vcl/metric.hxx>
00055 #endif
00056 #ifndef _SV_LINEINFO_HXX
00057 #include <vcl/lineinfo.hxx>
00058 #endif
00059 #ifndef _SV_OUTDEV_HXX //autogen
00060 #include <vcl/outdev.hxx>
00061 #endif
00062 #ifndef _SFXMODULE_HXX //autogen
00063 #include <sfx2/module.hxx>
00064 #endif
00065
00066
00067 #ifndef NODE_HXX
00068 #include "node.hxx"
00069 #endif
00070 #ifndef RECT_HXX
00071 #include <rect.hxx>
00072 #endif
00073 #ifndef SYMBOL_HXX
00074 #include "symbol.hxx"
00075 #endif
00076 #ifndef _SMMOD_HXX
00077 #include "smmod.hxx"
00078 #endif
00079 #ifndef DOCUMENT_HXX
00080 #include <document.hxx>
00081 #endif
00082 #ifndef VIEW_HXX
00083 #include <view.hxx>
00084 #endif
00085 #ifndef _MATHTYPE_HXX
00086 #include "mathtype.hxx"
00087 #endif
00088
00089 #include <math.h>
00090 #include <float.h>
00091
00092
00093
00094
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 class SmTmpDevice
00106 {
00107 OutputDevice &rOutDev;
00108
00109
00110 SmTmpDevice(const SmTmpDevice &rTmpDev);
00111 SmTmpDevice & operator = (const SmTmpDevice &rTmpDev);
00112
00113 Color Impl_GetColor( const Color& rColor );
00114
00115 public:
00116 SmTmpDevice(OutputDevice &rTheDev, BOOL bUseMap100th_mm);
00117 ~SmTmpDevice() { rOutDev.Pop(); }
00118
00119 void SetFont(const Font &rNewFont);
00120
00121 void SetLineColor( const Color& rColor ) { rOutDev.SetLineColor( Impl_GetColor(rColor) ); }
00122 void SetFillColor( const Color& rColor ) { rOutDev.SetFillColor( Impl_GetColor(rColor) ); }
00123 void SetTextColor( const Color& rColor ) { rOutDev.SetTextColor( Impl_GetColor(rColor) ); }
00124
00125 operator OutputDevice & () { return rOutDev; }
00126 };
00127
00128
00129 SmTmpDevice::SmTmpDevice(OutputDevice &rTheDev, BOOL bUseMap100th_mm) :
00130 rOutDev(rTheDev)
00131 {
00132 rOutDev.Push( PUSH_FONT | PUSH_MAPMODE |
00133 PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
00134 if (bUseMap100th_mm && MAP_100TH_MM != rOutDev.GetMapMode().GetMapUnit())
00135 {
00136 DBG_ERROR( "incorrect MapMode?" );
00137 rOutDev.SetMapMode( MAP_100TH_MM );
00138 }
00139 }
00140
00141
00142 Color SmTmpDevice::Impl_GetColor( const Color& rColor )
00143 {
00144 ColorData nNewCol = rColor.GetColor();
00145 if (COL_AUTO == nNewCol)
00146 {
00147 if (OUTDEV_PRINTER == rOutDev.GetOutDevType())
00148 nNewCol = COL_BLACK;
00149 else
00150 {
00151 Color aBgCol( rOutDev.GetBackground().GetColor() );
00152 if (OUTDEV_WINDOW == rOutDev.GetOutDevType())
00153 aBgCol = ((Window &) rOutDev).GetDisplayBackground().GetColor();
00154
00155 nNewCol = SM_MOD1()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
00156
00157 Color aTmpColor( nNewCol );
00158 if (aBgCol.IsDark() && aTmpColor.IsDark())
00159 nNewCol = COL_WHITE;
00160 else if (aBgCol.IsBright() && aTmpColor.IsBright())
00161 nNewCol = COL_BLACK;
00162 }
00163 }
00164 return Color( nNewCol );
00165 }
00166
00167
00168 void SmTmpDevice::SetFont(const Font &rNewFont)
00169 {
00170 rOutDev.SetFont( rNewFont );
00171 rOutDev.SetTextColor( Impl_GetColor( rNewFont.GetColor() ) );
00172 }
00173
00174
00176
00177
00178 SmNode::SmNode(SmNodeType eNodeType, const SmToken &rNodeToken)
00179 {
00180 eType = eNodeType;
00181 eScaleMode = SCALE_NONE;
00182 aNodeToken = rNodeToken;
00183 nAccIndex = -1;
00184 }
00185
00186
00187 SmNode::~SmNode()
00188 {
00189 }
00190
00191
00192 BOOL SmNode::IsVisible() const
00193 {
00194 return FALSE;
00195 }
00196
00197
00198 USHORT SmNode::GetNumSubNodes() const
00199 {
00200 return 0;
00201 }
00202
00203
00204 SmNode * SmNode::GetSubNode(USHORT )
00205 {
00206 return NULL;
00207 }
00208
00209
00210 SmNode * SmNode::GetLeftMost()
00211
00214 {
00215 SmNode *pNode = GetNumSubNodes() > 0 ?
00216 GetSubNode(0) : NULL;
00217
00218 return pNode ? pNode->GetLeftMost() : this;
00219 }
00220
00221
00222 void SmNode::SetPhantom(BOOL bIsPhantomP)
00223 {
00224 if (! (Flags() & FLG_VISIBLE))
00225 bIsPhantom = bIsPhantomP;
00226
00227 SmNode *pNode;
00228 USHORT nSize = GetNumSubNodes();
00229 for (USHORT i = 0; i < nSize; i++)
00230 if (NULL != (pNode = GetSubNode(i)))
00231 pNode->SetPhantom(bIsPhantom);
00232 }
00233
00234
00235 void SmNode::SetColor(const Color& rColor)
00236 {
00237 if (! (Flags() & FLG_COLOR))
00238 GetFont().SetColor(rColor);
00239
00240 SmNode *pNode;
00241 USHORT nSize = GetNumSubNodes();
00242 for (USHORT i = 0; i < nSize; i++)
00243 if (NULL != (pNode = GetSubNode(i)))
00244 pNode->SetColor(rColor);
00245 }
00246
00247
00248 void SmNode::SetAttribut(USHORT nAttrib)
00249 {
00250 if ( nAttrib == ATTR_BOLD && !(Flags() & FLG_BOLD)
00251 || nAttrib == ATTR_ITALIC && !(Flags() & FLG_ITALIC))
00252 nAttributes |= nAttrib;
00253
00254 SmNode *pNode;
00255 USHORT nSize = GetNumSubNodes();
00256 for (USHORT i = 0; i < nSize; i++)
00257 if (NULL != (pNode = GetSubNode(i)))
00258 pNode->SetAttribut(nAttrib);
00259 }
00260
00261
00262 void SmNode::ClearAttribut(USHORT nAttrib)
00263 {
00264 if ( nAttrib == ATTR_BOLD && !(Flags() & FLG_BOLD)
00265 || nAttrib == ATTR_ITALIC && !(Flags() & FLG_ITALIC))
00266 nAttributes &= ~nAttrib;
00267
00268 SmNode *pNode;
00269 USHORT nSize = GetNumSubNodes();
00270 for (USHORT i = 0; i < nSize; i++)
00271 if (NULL != (pNode = GetSubNode(i)))
00272 pNode->ClearAttribut(nAttrib);
00273 }
00274
00275
00276 void SmNode::SetFont(const SmFace &rFace)
00277 {
00278 if (!(Flags() & FLG_FONT))
00279 GetFont() = rFace;
00280
00281 SmNode *pNode;
00282 USHORT nSize = GetNumSubNodes();
00283 for (USHORT i = 0; i < nSize; i++)
00284 if (NULL != (pNode = GetSubNode(i)))
00285 pNode->SetFont(rFace);
00286 }
00287
00288
00289 void SmNode::SetFontSize(const Fraction &rSize, USHORT nType)
00291 {
00292 Size aFntSize;
00293
00294 if (!(Flags() & FLG_SIZE))
00295 {
00296 Fraction aVal (SmPtsTo100th_mm(rSize.GetNumerator()),
00297 rSize.GetDenominator());
00298
00299 long nHeight = (long)aVal;
00300
00301 aFntSize = GetFont().GetSize();
00302 aFntSize.Width() = 0;
00303 switch(nType)
00304 {
00305 case FNTSIZ_ABSOLUT:
00306 aFntSize.Height() = nHeight;
00307 break;
00308
00309 case FNTSIZ_PLUS:
00310 aFntSize.Height() += nHeight;
00311 break;
00312
00313 case FNTSIZ_MINUS:
00314 aFntSize.Height() -= nHeight;
00315 break;
00316
00317 case FNTSIZ_MULTIPLY:
00318 aFntSize.Height() = (long) (Fraction(aFntSize.Height()) * rSize);
00319 break;
00320
00321 case FNTSIZ_DIVIDE:
00322 if (rSize != Fraction(0L))
00323 aFntSize.Height() = (long) (Fraction(aFntSize.Height()) / rSize);
00324 break;
00325 default:
00326 break;
00327 }
00328
00329
00330 static int __READONLY_DATA nMaxVal = SmPtsTo100th_mm(128);
00331 if (aFntSize.Height() > nMaxVal)
00332 aFntSize.Height() = nMaxVal;
00333
00334 GetFont().SetSize(aFntSize);
00335 }
00336
00337 SmNode *pNode;
00338 USHORT nSize = GetNumSubNodes();
00339 for (USHORT i = 0; i < nSize; i++)
00340 if (NULL != (pNode = GetSubNode(i)))
00341 pNode->SetFontSize(rSize, nType);
00342 }
00343
00344
00345 void SmNode::SetSize(const Fraction &rSize)
00346 {
00347 GetFont() *= rSize;
00348
00349 SmNode *pNode;
00350 USHORT nSize = GetNumSubNodes();
00351 for (USHORT i = 0; i < nSize; i++)
00352 if (NULL != (pNode = GetSubNode(i)))
00353 pNode->SetSize(rSize);
00354 }
00355
00356
00357 void SmNode::SetRectHorAlign(RectHorAlign eHorAlign, BOOL bApplyToSubTree )
00358 {
00359 if (!(Flags() & FLG_HORALIGN))
00360 eRectHorAlign = eHorAlign;
00361
00362 if (bApplyToSubTree)
00363 {
00364 SmNode *pNode;
00365 USHORT nSize = GetNumSubNodes();
00366 for (USHORT i = 0; i < nSize; i++)
00367 if (NULL != (pNode = GetSubNode(i)))
00368 pNode->SetRectHorAlign(eHorAlign);
00369 }
00370 }
00371
00372
00373 void SmNode::PrepareAttributes()
00374 {
00375 GetFont().SetWeight((Attributes() & ATTR_BOLD) ? WEIGHT_BOLD : WEIGHT_NORMAL);
00376 GetFont().SetItalic((Attributes() & ATTR_ITALIC) ? ITALIC_NORMAL : ITALIC_NONE);
00377 }
00378
00379
00380 void SmNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
00381 {
00382 #if OSL_DEBUG_LEVEL > 1
00383 bIsDebug = TRUE;
00384 #else
00385 bIsDebug = FALSE;
00386 #endif
00387 bIsPhantom = FALSE;
00388 nFlags = 0;
00389 nAttributes = 0;
00390
00391 switch (rFormat.GetHorAlign())
00392 { case AlignLeft: eRectHorAlign = RHA_LEFT; break;
00393 case AlignCenter: eRectHorAlign = RHA_CENTER; break;
00394 case AlignRight: eRectHorAlign = RHA_RIGHT; break;
00395 }
00396
00397 GetFont() = rFormat.GetFont(FNT_MATH);
00398
00399 DBG_ASSERT( GetFont().GetCharSet() == RTL_TEXTENCODING_UNICODE,
00400 "unexpected CharSet" );
00401 GetFont().SetWeight(WEIGHT_NORMAL);
00402 GetFont().SetItalic(ITALIC_NONE);
00403
00404 SmNode *pNode;
00405 USHORT nSize = GetNumSubNodes();
00406 for (USHORT i = 0; i < nSize; i++)
00407 if (NULL != (pNode = GetSubNode(i)))
00408 pNode->Prepare(rFormat, rDocShell);
00409 }
00410
00411
00412 #if OSL_DEBUG_LEVEL > 1
00413 void SmNode::ToggleDebug() const
00414
00415 {
00416 SmNode *pThis = (SmNode *) this;
00417
00418 pThis->bIsDebug = bIsDebug ? FALSE : TRUE;
00419
00420 SmNode *pNode;
00421 USHORT nSize = GetNumSubNodes();
00422 for (USHORT i = 0; i < nSize; i++)
00423 if (NULL != (pNode = pThis->GetSubNode(i)))
00424 pNode->ToggleDebug();
00425 }
00426 #endif
00427
00428
00429 void SmNode::Move(const Point& rPosition)
00430 {
00431 if (rPosition.X() == 0 && rPosition.Y() == 0)
00432 return;
00433
00434 SmRect::Move(rPosition);
00435
00436 SmNode *pNode;
00437 USHORT nSize = GetNumSubNodes();
00438 for (USHORT i = 0; i < nSize; i++)
00439 if (NULL != (pNode = GetSubNode(i)))
00440 pNode->Move(rPosition);
00441 }
00442
00443
00444 void SmNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
00445 {
00446 SmNode *pNode;
00447 USHORT nSize = GetNumSubNodes();
00448 for (USHORT i = 0; i < nSize; i++)
00449 if (NULL != (pNode = GetSubNode(i)))
00450 pNode->Arrange(rDev, rFormat);
00451 }
00452
00453 void SmNode::CreateTextFromNode(String &rText)
00454 {
00455 SmNode *pNode;
00456 USHORT nSize = GetNumSubNodes();
00457 if (nSize > 1)
00458 rText.Append('{');
00459 for (USHORT i = 0; i < nSize; i++)
00460 if (NULL != (pNode = GetSubNode(i)))
00461 pNode->CreateTextFromNode(rText);
00462 if (nSize > 1)
00463 {
00464 rText.EraseTrailingChars();
00465 APPEND(rText,"} ");
00466 }
00467 }
00468
00469
00470 void SmNode::AdaptToX(const OutputDevice &, ULONG )
00471 {
00472 }
00473
00474
00475 void SmNode::AdaptToY(const OutputDevice &, ULONG )
00476 {
00477 }
00478
00479
00480 void SmNode::Draw(OutputDevice &rDev, const Point &rPosition) const
00481 {
00482 if (IsPhantom())
00483 return;
00484
00485 const SmNode *pNode;
00486 USHORT nSize = GetNumSubNodes();
00487 for (USHORT i = 0; i < nSize; i++)
00488 if (NULL != (pNode = GetSubNode(i)))
00489 { Point aOffset (pNode->GetTopLeft() - GetTopLeft());
00490 pNode->Draw(rDev, rPosition + aOffset);
00491 }
00492
00493 #ifdef SM_RECT_DEBUG
00494 if (!IsDebug())
00495 return;
00496
00497 int nRFlags = SM_RECT_CORE | SM_RECT_ITALIC | SM_RECT_LINES | SM_RECT_MID;
00498 SmRect::Draw(rDev, rPosition, nRFlags);
00499 #endif
00500 }
00501
00502 const SmNode * SmNode::FindTokenAt(USHORT nRow, USHORT nCol) const
00503
00504
00506 {
00507 if ( IsVisible()
00508 && nRow == GetToken().nRow
00509 && nCol >= GetToken().nCol && nCol < GetToken().nCol + GetToken().aText.Len())
00510 return this;
00511 else
00512 {
00513 USHORT nNumSubNodes = GetNumSubNodes();
00514 for (USHORT i = 0; i < nNumSubNodes; i++)
00515 { const SmNode *pNode = GetSubNode(i);
00516
00517 if (!pNode)
00518 continue;
00519
00520 const SmNode *pResult = pNode->FindTokenAt(nRow, nCol);
00521 if (pResult)
00522 return pResult;
00523 }
00524 }
00525
00526 return 0;
00527 }
00528
00529
00530 const SmNode * SmNode::FindRectClosestTo(const Point &rPoint) const
00531 {
00532 long nDist = LONG_MAX;
00533 const SmNode *pResult = 0;
00534
00535 if (IsVisible())
00536 pResult = this;
00537 else
00538 {
00539 USHORT nNumSubNodes = GetNumSubNodes();
00540 for (USHORT i = 0; i < nNumSubNodes; i++)
00541 { const SmNode *pNode = GetSubNode(i);
00542
00543 if (!pNode)
00544 continue;
00545
00546 long nTmp;
00547 const SmNode *pFound = pNode->FindRectClosestTo(rPoint);
00548 if (pFound && (nTmp = pFound->OrientedDist(rPoint)) < nDist)
00549 { nDist = nTmp;
00550 pResult = pFound;
00551
00552
00553
00554
00555
00556
00557
00558 if (nDist < 0 && pFound->IsInsideRect(rPoint))
00559 break;
00560 }
00561 }
00562 }
00563
00564 return pResult;
00565 }
00566
00567 void SmNode::GetAccessibleText( String & ) const
00568 {
00569 DBG_ERROR( "SmNode: GetAccessibleText not overloaded" );
00570 }
00571
00572 const SmNode * SmNode::FindNodeWithAccessibleIndex(xub_StrLen nAccIdx) const
00573 {
00574 const SmNode *pResult = 0;
00575
00576 sal_Int32 nIdx = GetAccessibleIndex();
00577 String aTxt;
00578 if (nIdx >= 0)
00579 GetAccessibleText( aTxt );
00580
00581 if (nIdx >= 0
00582 && nIdx <= nAccIdx && nAccIdx < nIdx + aTxt.Len())
00583 pResult = this;
00584 else
00585 {
00586 USHORT nNumSubNodes = GetNumSubNodes();
00587 for (USHORT i = 0; i < nNumSubNodes; i++)
00588 {
00589 const SmNode *pNode = GetSubNode(i);
00590 if (!pNode)
00591 continue;
00592
00593 pResult = pNode->FindNodeWithAccessibleIndex(nAccIdx);
00594 if (pResult)
00595 return pResult;
00596 }
00597 }
00598
00599 return pResult;
00600 }
00601
00603
00604 SmStructureNode::SmStructureNode( const SmStructureNode &rNode ) :
00605 SmNode( rNode.GetType(), rNode.GetToken() )
00606 {
00607 ULONG i;
00608 for (i = 0; i < aSubNodes.GetSize(); i++)
00609 delete aSubNodes.Get(i);
00610 aSubNodes.Clear();
00611
00612 ULONG nSize = rNode.aSubNodes.GetSize();
00613 aSubNodes.SetSize( nSize );
00614 for (i = 0; i < nSize; ++i)
00615 {
00616 SmNode *pNode = rNode.aSubNodes.Get(i);
00617 aSubNodes.Put( i, pNode ? new SmNode( *pNode ) : 0 );
00618 }
00619 }
00620
00621
00622 SmStructureNode::~SmStructureNode()
00623 {
00624 SmNode *pNode;
00625
00626 for (USHORT i = 0; i < GetNumSubNodes(); i++)
00627 if (NULL != (pNode = GetSubNode(i)))
00628 delete pNode;
00629 }
00630
00631
00632 SmStructureNode & SmStructureNode::operator = ( const SmStructureNode &rNode )
00633 {
00634 SmNode::operator = ( rNode );
00635
00636 ULONG i;
00637 for (i = 0; i < aSubNodes.GetSize(); i++)
00638 delete aSubNodes.Get(i);
00639 aSubNodes.Clear();
00640
00641 ULONG nSize = rNode.aSubNodes.GetSize();
00642 aSubNodes.SetSize( nSize );
00643 for (i = 0; i < nSize; ++i)
00644 {
00645 SmNode *pNode = rNode.aSubNodes.Get(i);
00646 aSubNodes.Put( i, pNode ? new SmNode( *pNode ) : 0 );
00647 }
00648
00649 return *this;
00650 }
00651
00652
00653 void SmStructureNode::SetSubNodes(SmNode *pFirst, SmNode *pSecond, SmNode *pThird)
00654 {
00655 if (pFirst)
00656 aSubNodes.Put(0, pFirst);
00657 if (pSecond)
00658 aSubNodes.Put(1, pSecond);
00659 if (pThird)
00660 aSubNodes.Put(2, pThird);
00661 }
00662
00663
00664 void SmStructureNode::SetSubNodes(const SmNodeArray &rNodeArray)
00665 {
00666 aSubNodes = rNodeArray;
00667 }
00668
00669
00670 BOOL SmStructureNode::IsVisible() const
00671 {
00672 return FALSE;
00673 }
00674
00675
00676 USHORT SmStructureNode::GetNumSubNodes() const
00677 {
00678 return (USHORT) aSubNodes.GetSize();
00679 }
00680
00681
00682 SmNode * SmStructureNode::GetSubNode(USHORT nIndex)
00683 {
00684 return aSubNodes.Get(nIndex);
00685 }
00686
00687
00688 void SmStructureNode::GetAccessibleText( String &rText ) const
00689 {
00690 USHORT nNodes = GetNumSubNodes();
00691 for (USHORT i = 0; i < nNodes; ++i)
00692 {
00693 const SmNode *pNode = ((SmStructureNode *) this)->GetSubNode(i);
00694 if (pNode)
00695 {
00696 if (pNode->IsVisible())
00697 ((SmStructureNode *) pNode)->nAccIndex = rText.Len();
00698 pNode->GetAccessibleText( rText );
00699
00700
00701 }
00702 }
00703 }
00704
00706
00707
00708 BOOL SmVisibleNode::IsVisible() const
00709 {
00710 return TRUE;
00711 }
00712
00713
00714 USHORT SmVisibleNode::GetNumSubNodes() const
00715 {
00716 return 0;
00717 }
00718
00719
00720 SmNode * SmVisibleNode::GetSubNode(USHORT )
00721 {
00722 return NULL;
00723 }
00724
00725
00727
00728 void SmGraphicNode::GetAccessibleText( String &rText ) const
00729 {
00730 rText += GetToken().aText;
00731 }
00732
00734
00735
00736 void SmExpressionNode::CreateTextFromNode(String &rText)
00737 {
00738 SmNode *pNode;
00739 USHORT nSize = GetNumSubNodes();
00740 if (nSize > 1)
00741 rText.Append('{');
00742 for (USHORT i = 0; i < nSize; i++)
00743 if (NULL != (pNode = GetSubNode(i)))
00744 {
00745 pNode->CreateTextFromNode(rText);
00746
00747 if (pNode->GetType() == NMATH)
00748 if ((nSize != 2) || ((rText.GetChar(rText.Len()-1) != '+') &&
00749 (rText.GetChar(rText.Len()-1) != '-')))
00750 rText.Append(' ');
00751 }
00752
00753 if (nSize > 1)
00754 {
00755 rText.EraseTrailingChars();
00756 APPEND(rText,"} ");
00757 }
00758 }
00759
00760
00762
00763 void SmTableNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
00764
00765 {
00766 Point rPosition;
00767
00768 SmNode *pNode;
00769 USHORT nSize = GetNumSubNodes();
00770
00771
00772 long nDist = +(rFormat.GetDistance(DIS_VERTICAL)
00773 * GetFont().GetSize().Height()) / 100L;
00774
00775 if (nSize < 1)
00776 return;
00777
00778
00779 long nMaxWidth = 0,
00780 nTmp;
00781 USHORT i;
00782 for (i = 0; i < nSize; i++)
00783 if (NULL != (pNode = GetSubNode(i)))
00784 { pNode->Arrange(rDev, rFormat);
00785 if ((nTmp = pNode->GetItalicWidth()) > nMaxWidth)
00786 nMaxWidth = nTmp;
00787 }
00788
00789 Point aPos;
00790 SmRect::operator = (SmRect(nMaxWidth, 0));
00791 for (i = 0; i < nSize; i++)
00792 { if (NULL != (pNode = GetSubNode(i)))
00793 { const SmRect &rNodeRect = pNode->GetRect();
00794 const SmNode *pCoNode = pNode->GetLeftMost();
00795
00796 RectHorAlign eHorAlign = pCoNode->GetRectHorAlign();
00797
00798 aPos = rNodeRect.AlignTo(*this, RP_BOTTOM,
00799 eHorAlign, RVA_BASELINE);
00800 if (i)
00801 aPos.Y() += nDist;
00802 pNode->MoveTo(aPos);
00803 ExtendBy(rNodeRect, nSize > 1 ? RCP_NONE : RCP_ARG);
00804 }
00805 }
00806 }
00807
00808
00809 SmNode * SmTableNode::GetLeftMost()
00810 {
00811 return this;
00812 }
00813
00814
00815
00816
00817
00818 void SmLineNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
00819 {
00820 SmNode::Prepare(rFormat, rDocShell);
00821
00824 GetFont() = rFormat.GetFont(FNT_VARIABLE);
00825 Flags() |= FLG_FONT;
00826 }
00827
00828
00829
00830
00831
00832 void SmLineNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
00833
00834 {
00835 SmNode *pNode;
00836 USHORT nSize = GetNumSubNodes();
00837 USHORT i;
00838 for (i = 0; i < nSize; i++)
00839 if (NULL != (pNode = GetSubNode(i)))
00840 pNode->Arrange(rDev, rFormat);
00841
00842 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
00843 aTmpDev.SetFont(GetFont());
00844
00845
00846
00847
00851 SmRect::operator = (SmRect(aTmpDev, &rFormat, C2S("a"),
00852 GetFont().GetBorderWidth()));
00853
00854 SetWidth(1);
00855 SetItalicSpaces(0, 0);
00856
00857 if (nSize < 1)
00858 return;
00859
00860
00861 long nDist = +(rFormat.GetDistance(DIS_HORIZONTAL)
00862 * GetFont().GetSize().Height()) / 100L;
00863
00864 Point aPos;
00865 for (i = 0; i < nSize; i++)
00866 if (NULL != (pNode = GetSubNode(i)))
00867 {
00868 aPos = pNode->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
00869
00870
00871 if (i)
00872 aPos.X() += nDist;
00873
00874 pNode->MoveTo(aPos);
00875 ExtendBy( *pNode, RCP_XOR );
00876 }
00877 }
00878
00879
00880
00881
00882
00883 void SmExpressionNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
00884
00885 {
00886 DBG_ASSERT(GetNumSubNodes() > 0, "Sm: keine subnodes");
00887
00888 SmLineNode::Arrange(rDev, rFormat);
00889
00890
00891 SmNode *pNode = GetLeftMost();
00892 if (pNode)
00893 SetRectHorAlign(pNode->GetRectHorAlign(), FALSE);
00894 }
00895
00896
00897
00898
00899
00900 void SmUnHorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
00901 {
00902 BOOL bIsPostfix = GetToken().eType == TFACT;
00903
00904 SmNode *pOper = GetSubNode(bIsPostfix ? 1 : 0),
00905 *pBody = GetSubNode(bIsPostfix ? 0 : 1);
00906 DBG_ASSERT(pOper, "Sm: NULL pointer");
00907 DBG_ASSERT(pBody, "Sm: NULL pointer");
00908
00909 pOper->SetSize(Fraction (rFormat.GetRelSize(SIZ_OPERATOR), 100));
00910 pOper->Arrange(rDev, rFormat);
00911 pBody->Arrange(rDev, rFormat);
00912
00913 Point aPos = pOper->AlignTo(*pBody, bIsPostfix ? RP_RIGHT : RP_LEFT,
00914 RHA_CENTER, RVA_BASELINE);
00915
00916
00917 long nDelta = pOper->GetFont().GetSize().Height() / 20;
00918 if (bIsPostfix)
00919 aPos.X() += nDelta;
00920 else
00921 aPos.X() -= nDelta;
00922 pOper->MoveTo(aPos);
00923
00924 SmRect::operator = (*pBody);
00925 long nOldBot = GetBottom();
00926
00927 ExtendBy(*pOper, RCP_XOR);
00928
00929
00930
00931 SetBottom(nOldBot);
00932 }
00933
00934
00935
00936
00937
00938 void SmRootNode::GetHeightVerOffset(const SmRect &rRect,
00939 long &rHeight, long &rVerOffset) const
00940
00941 {
00942 rVerOffset = (rRect.GetBottom() - rRect.GetAlignB()) / 2;
00943 rHeight = rRect.GetHeight() - rVerOffset;
00944
00945 DBG_ASSERT(rHeight >= 0, "Sm : Ooops...");
00946 DBG_ASSERT(rVerOffset >= 0, "Sm : Ooops...");
00947 }
00948
00949
00950 Point SmRootNode::GetExtraPos(const SmRect &rRootSymbol,
00951 const SmRect &rExtra) const
00952 {
00953 const Size &rSymSize = rRootSymbol.GetSize();
00954
00955 Point aPos = rRootSymbol.GetTopLeft()
00956 + Point((rSymSize.Width() * 70) / 100,
00957 (rSymSize.Height() * 52) / 100);
00958
00959
00960 aPos.X() -= rExtra.GetWidth() + rExtra.GetItalicRightSpace();
00961 aPos.Y() -= rExtra.GetHeight();
00962
00963
00964
00965 long nX = rRootSymbol.GetLeft() + (rSymSize.Width() * 30) / 100;
00966 if (aPos.X() > nX)
00967 aPos.X() = nX;
00968
00969 return aPos;
00970 }
00971
00972
00973 void SmRootNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
00974 {
00979 SmNode *pExtra = GetSubNode(0),
00980 *pRootSym = GetSubNode(1),
00981 *pBody = GetSubNode(2);
00982 DBG_ASSERT(pRootSym, "Sm: NULL pointer");
00983 DBG_ASSERT(pBody, "Sm: NULL pointer");
00984
00985 pBody->Arrange(rDev, rFormat);
00986
00987 long nHeight,
00988 nVerOffset;
00989 GetHeightVerOffset(*pBody, nHeight, nVerOffset);
00990 nHeight += rFormat.GetDistance(DIS_ROOT)
00991 * GetFont().GetSize().Height() / 100L;
00992
00993
00994 pRootSym->AdaptToY(rDev, nHeight);
00995 pRootSym->AdaptToX(rDev, pBody->GetItalicWidth());
00996
00997 pRootSym->Arrange(rDev, rFormat);
00998
00999 Point aPos = pRootSym->AlignTo(*pBody, RP_LEFT, RHA_CENTER, RVA_BASELINE);
01001 aPos.Y() = pRootSym->GetTop() + pBody->GetBottom() - pRootSym->GetBottom();
01002 aPos.Y() -= nVerOffset;
01003 pRootSym->MoveTo(aPos);
01004
01005 if (pExtra)
01006 { pExtra->SetSize(Fraction(rFormat.GetRelSize(SIZ_INDEX), 100));
01007 pExtra->Arrange(rDev, rFormat);
01008
01009 aPos = GetExtraPos(*pRootSym, *pExtra);
01010 pExtra->MoveTo(aPos);
01011 }
01012
01013 SmRect::operator = (*pBody);
01014 ExtendBy(*pRootSym, RCP_THIS);
01015 if (pExtra)
01016 ExtendBy(*pExtra, RCP_THIS, (BOOL) TRUE);
01017 }
01018
01019
01020 void SmRootNode::CreateTextFromNode(String &rText)
01021 {
01022 SmNode *pExtra = GetSubNode(0);
01023 if (pExtra)
01024 {
01025 APPEND(rText,"nroot ");
01026 pExtra->CreateTextFromNode(rText);
01027 }
01028 else
01029 APPEND(rText,"sqrt ");
01030 GetSubNode(2)->CreateTextFromNode(rText);
01031 }
01032
01033
01034
01035
01036
01037 void SmBinHorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01038 {
01039 SmNode *pLeft = GetSubNode(0),
01040 *pOper = GetSubNode(1),
01041 *pRight = GetSubNode(2);
01042 DBG_ASSERT(pLeft != NULL, "Sm: NULL pointer");
01043 DBG_ASSERT(pOper != NULL, "Sm: NULL pointer");
01044 DBG_ASSERT(pRight != NULL, "Sm: NULL pointer");
01045
01046 pOper->SetSize(Fraction (rFormat.GetRelSize(SIZ_OPERATOR), 100));
01047
01048 pLeft ->Arrange(rDev, rFormat);
01049 pOper ->Arrange(rDev, rFormat);
01050 pRight->Arrange(rDev, rFormat);
01051
01052 const SmRect &rOpRect = pOper->GetRect();
01053
01054 long nDist = (rOpRect.GetWidth() *
01055 rFormat.GetDistance(DIS_HORIZONTAL)) / 100L;
01056
01057 SmRect::operator = (*pLeft);
01058
01059 Point aPos;
01060 aPos = pOper->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
01061 aPos.X() += nDist;
01062 pOper->MoveTo(aPos);
01063 ExtendBy(*pOper, RCP_XOR);
01064
01065 aPos = pRight->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
01066 aPos.X() += nDist;
01067
01068 pRight->MoveTo(aPos);
01069 ExtendBy(*pRight, RCP_XOR);
01070 }
01071
01072
01073
01074
01075
01076 void SmBinVerNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01077 {
01078 SmNode *pNum = GetSubNode(0),
01079 *pLine = GetSubNode(1),
01080 *pDenom = GetSubNode(2);
01081 DBG_ASSERT(pNum, "Sm : NULL pointer");
01082 DBG_ASSERT(pLine, "Sm : NULL pointer");
01083 DBG_ASSERT(pDenom, "Sm : NULL pointer");
01084
01085 BOOL bIsTextmode = rFormat.IsTextmode();
01086 if (bIsTextmode)
01087 {
01088 Fraction aFraction(rFormat.GetRelSize(SIZ_INDEX), 100);
01089 pNum ->SetSize(aFraction);
01090 pLine ->SetSize(aFraction);
01091 pDenom->SetSize(aFraction);
01092 }
01093
01094 pNum ->Arrange(rDev, rFormat);
01095 pDenom->Arrange(rDev, rFormat);
01096
01097 long nFontHeight = GetFont().GetSize().Height(),
01098 nExtLen = nFontHeight * rFormat.GetDistance(DIS_FRACTION) / 100L,
01099 nThick = nFontHeight * rFormat.GetDistance(DIS_STROKEWIDTH) / 100L,
01100 nWidth = Max(pNum->GetItalicWidth(), pDenom->GetItalicWidth()),
01101 nNumDist = bIsTextmode ? 0 :
01102 nFontHeight * rFormat.GetDistance(DIS_NUMERATOR) / 100L,
01103 nDenomDist = bIsTextmode ? 0 :
01104 nFontHeight * rFormat.GetDistance(DIS_DENOMINATOR) / 100L;
01105
01106
01107 pLine->AdaptToY(rDev, nThick);
01108 pLine->AdaptToX(rDev, nWidth + 2 * nExtLen);
01109 pLine->Arrange(rDev, rFormat);
01110
01111
01112 const SmNode *pLM = pNum->GetLeftMost();
01113 RectHorAlign eHorAlign = pLM->GetRectHorAlign();
01114
01115
01116 Point aPos = pNum->AlignTo(*pLine, RP_TOP, eHorAlign, RVA_BASELINE);
01117 aPos.Y() -= nNumDist;
01118 pNum->MoveTo(aPos);
01119
01120
01121 pLM = pDenom->GetLeftMost();
01122 eHorAlign = pLM->GetRectHorAlign();
01123
01124
01125 aPos = pDenom->AlignTo(*pLine, RP_BOTTOM, eHorAlign, RVA_BASELINE);
01126 aPos.Y() += nDenomDist;
01127 pDenom->MoveTo(aPos);
01128
01129 SmRect::operator = (*pNum);
01130 ExtendBy(*pDenom, RCP_NONE).ExtendBy(*pLine, RCP_NONE, pLine->GetCenterY());
01131 }
01132
01133 void SmBinVerNode::CreateTextFromNode(String &rText)
01134 {
01135 SmNode *pNum = GetSubNode(0),
01136
01137 *pDenom = GetSubNode(2);
01138 pNum->CreateTextFromNode(rText);
01139 APPEND(rText,"over ");
01140 pDenom->CreateTextFromNode(rText);
01141 }
01142
01143
01144 SmNode * SmBinVerNode::GetLeftMost()
01145 {
01146 return this;
01147 }
01148
01149
01150
01151
01152
01153 double Det(const Point &rHeading1, const Point &rHeading2)
01154
01155
01156 {
01157 return rHeading1.X() * rHeading2.Y() - rHeading1.Y() * rHeading2.X();
01158 }
01159
01160
01161 BOOL IsPointInLine(const Point &rPoint1,
01162 const Point &rPoint2, const Point &rHeading2)
01163
01164
01165 {
01166 DBG_ASSERT(rHeading2 != Point(), "Sm : 0 vector");
01167
01168 BOOL bRes = FALSE;
01169 const double eps = 5.0 * DBL_EPSILON;
01170
01171 double fLambda;
01172 if (labs(rHeading2.X()) > labs(rHeading2.Y()))
01173 {
01174 fLambda = (rPoint1.X() - rPoint2.X()) / (double) rHeading2.X();
01175 bRes = fabs(rPoint1.Y() - (rPoint2.Y() + fLambda * rHeading2.Y())) < eps;
01176 }
01177 else
01178 {
01179 fLambda = (rPoint1.Y() - rPoint2.Y()) / (double) rHeading2.Y();
01180 bRes = fabs(rPoint1.X() - (rPoint2.X() + fLambda * rHeading2.X())) < eps;
01181 }
01182
01183 return bRes;
01184 }
01185
01186
01187 USHORT GetLineIntersectionPoint(Point &rResult,
01188 const Point& rPoint1, const Point &rHeading1,
01189 const Point& rPoint2, const Point &rHeading2)
01190 {
01191 DBG_ASSERT(rHeading1 != Point(), "Sm : 0 vector");
01192 DBG_ASSERT(rHeading2 != Point(), "Sm : 0 vector");
01193
01194 USHORT nRes = 1;
01195 const double eps = 5.0 * DBL_EPSILON;
01196
01197
01198 double fDet = Det(rHeading1, rHeading2);
01199 if (fabs(fDet) < eps)
01200 {
01201 nRes = IsPointInLine(rPoint1, rPoint2, rHeading2) ? USHRT_MAX : 0;
01202 rResult = nRes ? rPoint1 : Point();
01203 }
01204 else
01205 {
01206
01207
01208 double fLambda = ( (rPoint1.Y() - rPoint2.Y()) * rHeading2.X()
01209 - (rPoint1.X() - rPoint2.X()) * rHeading2.Y())
01210 / fDet;
01211 rResult = Point(rPoint1.X() + (long) (fLambda * rHeading1.X()),
01212 rPoint1.Y() + (long) (fLambda * rHeading1.Y()));
01213 }
01214
01215 return nRes;
01216 }
01217
01218
01219
01220 SmBinDiagonalNode::SmBinDiagonalNode(const SmToken &rNodeToken)
01221 : SmStructureNode(NBINDIAGONAL, rNodeToken)
01222 {
01223 bAscending = FALSE;
01224 SetNumSubNodes(3);
01225 }
01226
01227
01228 void SmBinDiagonalNode::GetOperPosSize(Point &rPos, Size &rSize,
01229 const Point &rDiagPoint, double fAngleDeg) const
01230
01231
01232
01233
01234 {
01235 const double fPi = 3.1415926535897932384626433;
01236 double fAngleRad = fAngleDeg / 180.0 * fPi;
01237 long nRectLeft = GetItalicLeft(),
01238 nRectRight = GetItalicRight(),
01239 nRectTop = GetTop(),
01240 nRectBottom = GetBottom();
01241 Point aRightHdg (100, 0),
01242 aDownHdg (0, 100),
01243 aDiagHdg ( (long)(100.0 * cos(fAngleRad)),
01244 (long)(-100.0 * sin(fAngleRad)) );
01245
01246 long nLeft, nRight, nTop, nBottom;
01247
01248 Point aPoint;
01249 if (IsAscending())
01250 {
01251
01252
01253
01254 GetLineIntersectionPoint(aPoint,
01255 Point(nRectLeft, nRectTop), aRightHdg,
01256 rDiagPoint, aDiagHdg);
01257
01258
01259 if (aPoint.X() <= nRectRight)
01260 {
01261 nRight = aPoint.X();
01262 nTop = nRectTop;
01263 }
01264 else
01265 {
01266
01267 GetLineIntersectionPoint(aPoint,
01268 Point(nRectRight, nRectTop), aDownHdg,
01269 rDiagPoint, aDiagHdg);
01270
01271 nRight = nRectRight;
01272 nTop = aPoint.Y();
01273 }
01274
01275
01276
01277
01278 GetLineIntersectionPoint(aPoint,
01279 Point(nRectLeft, nRectBottom), aRightHdg,
01280 rDiagPoint, aDiagHdg);
01281
01282
01283 if (aPoint.X() >= nRectLeft)
01284 {
01285 nLeft = aPoint.X();
01286 nBottom = nRectBottom;
01287 }
01288 else
01289 {
01290
01291 GetLineIntersectionPoint(aPoint,
01292 Point(nRectLeft, nRectTop), aDownHdg,
01293 rDiagPoint, aDiagHdg);
01294
01295 nLeft = nRectLeft;
01296 nBottom = aPoint.Y();
01297 }
01298 }
01299 else
01300 {
01301
01302
01303
01304 GetLineIntersectionPoint(aPoint,
01305 Point(nRectLeft, nRectTop), aRightHdg,
01306 rDiagPoint, aDiagHdg);
01307
01308
01309 if (aPoint.X() >= nRectLeft)
01310 {
01311 nLeft = aPoint.X();
01312 nTop = nRectTop;
01313 }
01314 else
01315 {
01316
01317 GetLineIntersectionPoint(aPoint,
01318 Point(nRectLeft, nRectTop), aDownHdg,
01319 rDiagPoint, aDiagHdg);
01320
01321 nLeft = nRectLeft;
01322 nTop = aPoint.Y();
01323 }
01324
01325
01326
01327
01328 GetLineIntersectionPoint(aPoint,
01329 Point(nRectLeft, nRectBottom), aRightHdg,
01330 rDiagPoint, aDiagHdg);
01331
01332
01333 if (aPoint.X() <= nRectRight)
01334 {
01335 nRight = aPoint.X();
01336 nBottom = nRectBottom;
01337 }
01338 else
01339 {
01340
01341 GetLineIntersectionPoint(aPoint,
01342 Point(nRectRight, nRectTop), aDownHdg,
01343 rDiagPoint, aDiagHdg);
01344
01345 nRight = nRectRight;
01346 nBottom = aPoint.Y();
01347 }
01348 }
01349
01350 rSize = Size(nRight - nLeft + 1, nBottom - nTop + 1);
01351 rPos.X() = nLeft;
01352 rPos.Y() = nTop;
01353 }
01354
01355
01356 void SmBinDiagonalNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01357 {
01361 SmNode *pLeft = GetSubNode(0),
01362 *pRight = GetSubNode(1);
01363 DBG_ASSERT(pLeft, "Sm : NULL pointer");
01364 DBG_ASSERT(pRight, "Sm : NULL pointer");
01365
01366 DBG_ASSERT(GetSubNode(2)->GetType() == NPOLYLINE, "Sm : falscher Nodetyp");
01367 SmPolyLineNode *pOper = (SmPolyLineNode *) GetSubNode(2);
01368 DBG_ASSERT(pOper, "Sm : NULL pointer");
01369
01373 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
01374 aTmpDev.SetFont(GetFont());
01375
01376 pLeft->Arrange(aTmpDev, rFormat);
01377 pRight->Arrange(aTmpDev, rFormat);
01378
01379
01380 pOper->Arrange(aTmpDev, rFormat);
01381
01382 long nDelta = pOper->GetWidth() * 8 / 10;
01383
01384
01385 Point aPos;
01386 aPos.X() = pLeft->GetItalicRight() + nDelta + pRight->GetItalicLeftSpace();
01387 if (IsAscending())
01388 aPos.Y() = pLeft->GetBottom() + nDelta;
01389 else
01390 aPos.Y() = pLeft->GetTop() - nDelta - pRight->GetHeight();
01391
01392 pRight->MoveTo(aPos);
01393
01394
01395 long nTmpBaseline = IsAscending() ? (pLeft->GetBottom() + pRight->GetTop()) / 2
01396 : (pLeft->GetTop() + pRight->GetBottom()) / 2;
01397 Point aLogCenter ((pLeft->GetItalicRight() + pRight->GetItalicLeft()) / 2,
01398 nTmpBaseline);
01399
01400 SmRect::operator = (*pLeft);
01401 ExtendBy(*pRight, RCP_NONE);
01402
01403
01404
01405 Size aTmpSize;
01406 GetOperPosSize(aPos, aTmpSize, aLogCenter, IsAscending() ? 60.0 : -60.0);
01407
01408
01409 pOper->AdaptToY(aTmpDev, aTmpSize.Height());
01410 pOper->AdaptToX(aTmpDev, aTmpSize.Width());
01411
01412 pOper->Arrange(aTmpDev, rFormat);
01413
01414 pOper->MoveTo(aPos);
01415
01416 ExtendBy(*pOper, RCP_NONE, nTmpBaseline);
01417 }
01418
01419
01420
01421
01422
01423 void SmSubSupNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01424 {
01425 DBG_ASSERT(GetNumSubNodes() == 1 + SUBSUP_NUM_ENTRIES,
01426 "Sm: falsche Anzahl von subnodes");
01427
01428 SmNode *pBody = GetBody();
01429 DBG_ASSERT(pBody, "Sm: NULL pointer");
01430
01431 long nOrigHeight = pBody->GetFont().GetSize().Height();
01432
01433 pBody->Arrange(rDev, rFormat);
01434
01435 const SmRect &rBodyRect = pBody->GetRect();
01436 SmRect::operator = (rBodyRect);
01437
01438
01439 long nDelimLine = SmFromTo(GetAlignB(), GetAlignT(), 0.4);
01440
01441 Point aPos;
01442 long nDelta, nDist;
01443
01444
01445 SmRect aTmpRect (rBodyRect);
01446 for (int i = 0; i < SUBSUP_NUM_ENTRIES; i++)
01447 { SmSubSup eSubSup = (SmSubSup) i;
01448 SmNode *pSubSup = GetSubSup(eSubSup);
01449
01450 if (!pSubSup)
01451 continue;
01452
01453
01454 if (rFormat.IsTextmode() && (GetToken().nGroup & TGLIMIT))
01455 switch (eSubSup)
01456 { case CSUB: eSubSup = RSUB; break;
01457 case CSUP: eSubSup = RSUP; break;
01458 default:
01459 break;
01460 }
01461
01462
01463
01464 if (GetFont().GetSize().Height() > rFormat.GetBaseSize().Height() / 3)
01465 {
01466 USHORT nIndex = (eSubSup == CSUB || eSubSup == CSUP) ?
01467 SIZ_LIMITS : SIZ_INDEX;
01468 Fraction aFraction ( rFormat.GetRelSize(nIndex), 100 );
01469 pSubSup->SetSize(aFraction);
01470 }
01471
01472 pSubSup->Arrange(rDev, rFormat);
01473
01474 BOOL bIsTextmode = rFormat.IsTextmode();
01475 nDist = 0;
01476
01478 switch (eSubSup)
01479 { case RSUB :
01480 case LSUB :
01481 if (!bIsTextmode)
01482 nDist = nOrigHeight
01483 * rFormat.GetDistance(DIS_SUBSCRIPT) / 100L;
01484 aPos = pSubSup->GetRect().AlignTo(aTmpRect,
01485 eSubSup == LSUB ? RP_LEFT : RP_RIGHT,
01486 RHA_CENTER, RVA_BOTTOM);
01487 aPos.Y() += nDist;
01488 nDelta = nDelimLine - aPos.Y();
01489 if (nDelta > 0)
01490 aPos.Y() += nDelta;
01491 break;
01492 case RSUP :
01493 case LSUP :
01494 if (!bIsTextmode)
01495 nDist = nOrigHeight
01496 * rFormat.GetDistance(DIS_SUPERSCRIPT) / 100L;
01497 aPos = pSubSup->GetRect().AlignTo(aTmpRect,
01498 eSubSup == LSUP ? RP_LEFT : RP_RIGHT,
01499 RHA_CENTER, RVA_TOP);
01500 aPos.Y() -= nDist;
01501 nDelta = aPos.Y() + pSubSup->GetHeight() - nDelimLine;
01502 if (nDelta > 0)
01503 aPos.Y() -= nDelta;
01504 break;
01505 case CSUB :
01506 if (!bIsTextmode)
01507 nDist = nOrigHeight
01508 * rFormat.GetDistance(DIS_LOWERLIMIT) / 100L;
01509 aPos = pSubSup->GetRect().AlignTo(rBodyRect, RP_BOTTOM,
01510 RHA_CENTER, RVA_BASELINE);
01511 aPos.Y() += nDist;
01512 break;
01513 case CSUP :
01514 if (!bIsTextmode)
01515 nDist = nOrigHeight
01516 * rFormat.GetDistance(DIS_UPPERLIMIT) / 100L;
01517 aPos = pSubSup->GetRect().AlignTo(rBodyRect, RP_TOP,
01518 RHA_CENTER, RVA_BASELINE);
01519 aPos.Y() -= nDist;
01520 break;
01521 default :
01522 DBG_ASSERT(FALSE, "Sm: unbekannter Fall");
01523 break;
01524 }
01525
01526 pSubSup->MoveTo(aPos);
01527 ExtendBy(*pSubSup, RCP_THIS, (BOOL) TRUE);
01528
01529
01530
01531 if (eSubSup == CSUB || eSubSup == CSUP)
01532 aTmpRect = *this;
01533 }
01534 }
01535
01536 void SmSubSupNode::CreateTextFromNode(String &rText)
01537 {
01538 SmNode *pNode;
01539 GetSubNode(0)->CreateTextFromNode(rText);
01540
01541 if (NULL != (pNode = GetSubNode(LSUB+1)))
01542 {
01543 APPEND(rText,"lsub ");
01544 pNode->CreateTextFromNode(rText);
01545 }
01546 if (NULL != (pNode = GetSubNode(LSUP+1)))
01547 {
01548 APPEND(rText,"lsup ");
01549 pNode->CreateTextFromNode(rText);
01550 }
01551 if (NULL != (pNode = GetSubNode(CSUB+1)))
01552 {
01553 APPEND(rText,"csub ");
01554 pNode->CreateTextFromNode(rText);
01555 }
01556 if (NULL != (pNode = GetSubNode(CSUP+1)))
01557 {
01558 APPEND(rText,"csup ");
01559 pNode->CreateTextFromNode(rText);
01560 }
01561 if (NULL != (pNode = GetSubNode(RSUB+1)))
01562 {
01563 rText.EraseTrailingChars();
01564 rText.Append('_');
01565 pNode->CreateTextFromNode(rText);
01566 }
01567 if (NULL != (pNode = GetSubNode(RSUP+1)))
01568 {
01569 rText.EraseTrailingChars();
01570 rText.Append('^');
01571 pNode->CreateTextFromNode(rText);
01572 }
01573 }
01574
01575
01576
01577
01578 void SmBraceNode::CreateTextFromNode(String &rText)
01579 {
01580 if (GetScaleMode() == SCALE_HEIGHT)
01581 APPEND(rText,"left ");
01582 {
01583 String aStr;
01584 GetSubNode(0)->CreateTextFromNode(aStr);
01585 aStr.EraseLeadingAndTrailingChars();
01586 aStr.EraseLeadingChars('\\');
01587 if (aStr.Len())
01588 {
01589 if (aStr.EqualsAscii("divides"))
01590 APPEND(rText,"lline");
01591 else if (aStr.EqualsAscii("parallel"))
01592 APPEND(rText,"ldline");
01593 else if (aStr.EqualsAscii("<"))
01594 APPEND(rText,"langle");
01595 else
01596 rText.Append(aStr);
01597 rText.Append(' ');
01598 }
01599 else
01600 APPEND(rText,"none ");
01601 }
01602 GetSubNode(1)->CreateTextFromNode(rText);
01603 if (GetScaleMode() == SCALE_HEIGHT)
01604 APPEND(rText,"right ");
01605 {
01606 String aStr;
01607 GetSubNode(2)->CreateTextFromNode(aStr);
01608 aStr.EraseLeadingAndTrailingChars();
01609 aStr.EraseLeadingChars('\\');
01610 if (aStr.Len())
01611 {
01612 if (aStr.EqualsAscii("divides"))
01613 APPEND(rText,"rline");
01614 else if (aStr.EqualsAscii("parallel"))
01615 APPEND(rText,"rdline");
01616 else if (aStr.EqualsAscii(">"))
01617 APPEND(rText,"rangle");
01618 else
01619 rText.Append(aStr);
01620 rText.Append(' ');
01621 }
01622 else
01623 APPEND(rText,"none ");
01624 }
01625 rText.Append(' ');
01626
01627 }
01628
01629 void SmBraceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01630 {
01631 SmNode *pLeft = GetSubNode(0),
01632 *pBody = GetSubNode(1),
01633 *pRight = GetSubNode(2);
01634 DBG_ASSERT(pLeft, "Sm: NULL pointer");
01635 DBG_ASSERT(pBody, "Sm: NULL pointer");
01636 DBG_ASSERT(pRight, "Sm: NULL pointer");
01637
01638 pBody->Arrange(rDev, rFormat);
01639
01640 BOOL bIsScaleNormal = rFormat.IsScaleNormalBrackets(),
01641 bScale = pBody->GetHeight() > 0 &&
01642 (GetScaleMode() == SCALE_HEIGHT || bIsScaleNormal),
01643 bIsABS = GetToken().eType == TABS;
01644
01645 long nFaceHeight = GetFont().GetSize().Height();
01646
01647
01648 USHORT nPerc = 0;
01649 if (!bIsABS && bScale)
01650 {
01651 USHORT nIndex = GetScaleMode() == SCALE_HEIGHT ?
01652 DIS_BRACKETSIZE : DIS_NORMALBRACKETSIZE;
01653 nPerc = rFormat.GetDistance(nIndex);
01654 }
01655
01656
01657 long nBraceHeight;
01658 if (bScale)
01659 {
01660 nBraceHeight = pBody->GetType() == NBRACEBODY ?
01661 ((SmBracebodyNode *) pBody)->GetBodyHeight()
01662 : pBody->GetHeight();
01663 nBraceHeight += 2 * (nBraceHeight * nPerc / 100L);
01664 }
01665 else
01666 nBraceHeight = nFaceHeight;
01667
01668
01669 nPerc = bIsABS ? 0 : rFormat.GetDistance(DIS_BRACKETSPACE);
01670 long nDist = nFaceHeight * nPerc / 100L;
01671
01672
01673 if (bScale)
01674 {
01675 Size aTmpSize (pLeft->GetFont().GetSize());
01676 DBG_ASSERT(pRight->GetFont().GetSize() == aTmpSize,
01677 "Sm : unterschiedliche Fontgroessen");
01678 aTmpSize.Width() = Min((long) nBraceHeight * 60L / 100L,
01679 rFormat.GetBaseSize().Height() * 3L / 2L);
01680
01681
01682 aTmpSize.Width() *= 182;
01683 aTmpSize.Width() /= 267;
01684
01685 xub_Unicode cChar = pLeft->GetToken().cMathChar;
01686 if (cChar != MS_LINE && cChar != MS_DLINE)
01687 pLeft ->GetFont().SetSize(aTmpSize);
01688
01689 cChar = pRight->GetToken().cMathChar;
01690 if (cChar != MS_LINE && cChar != MS_DLINE)
01691 pRight->GetFont().SetSize(aTmpSize);
01692
01693 pLeft ->AdaptToY(rDev, nBraceHeight);
01694 pRight->AdaptToY(rDev, nBraceHeight);
01695 }
01696
01697 pLeft ->Arrange(rDev, rFormat);
01698 pRight->Arrange(rDev, rFormat);
01699
01700
01701 RectVerAlign eVerAlign = bScale ? RVA_CENTERY : RVA_BASELINE;
01702
01703 Point aPos;
01704 aPos = pLeft->AlignTo(*pBody, RP_LEFT, RHA_CENTER, eVerAlign);
01705 aPos.X() -= nDist;
01706 pLeft->MoveTo(aPos);
01707
01708 aPos = pRight->AlignTo(*pBody, RP_RIGHT, RHA_CENTER, eVerAlign);
01709 aPos.X() += nDist;
01710 pRight->MoveTo(aPos);
01711
01712 SmRect::operator = (*pBody);
01713 ExtendBy(*pLeft, RCP_THIS).ExtendBy(*pRight, RCP_THIS);
01714 }
01715
01716
01717
01718
01719
01720 void SmBracebodyNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01721 {
01722 USHORT nNumSubNodes = GetNumSubNodes();
01723 if (nNumSubNodes == 0)
01724 return;
01725
01726
01727 USHORT i;
01728 for (i = 0; i < nNumSubNodes; i += 2)
01729 GetSubNode(i)->Arrange(rDev, rFormat);
01730
01731
01732 SmRect aRefRect (*GetSubNode(0));
01733 for (i = 0; i < nNumSubNodes; i += 2)
01734 {
01735 SmRect aTmpRect (*GetSubNode(i));
01736 Point aPos = aTmpRect.AlignTo(aRefRect, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
01737 aTmpRect.MoveTo(aPos);
01738 aRefRect.ExtendBy(aTmpRect, RCP_XOR);
01739 }
01740
01741 nBodyHeight = aRefRect.GetHeight();
01742
01743
01744 BOOL bScale = GetScaleMode() == SCALE_HEIGHT || rFormat.IsScaleNormalBrackets();
01745 long nHeight = bScale ? aRefRect.GetHeight() : GetFont().GetSize().Height();
01746 USHORT nIndex = GetScaleMode() == SCALE_HEIGHT ?
01747 DIS_BRACKETSIZE : DIS_NORMALBRACKETSIZE;
01748 USHORT nPerc = rFormat.GetDistance(nIndex);
01749 if (bScale)
01750 nHeight += 2 * (nHeight * nPerc / 100L);
01751 for (i = 1; i < nNumSubNodes; i += 2)
01752 {
01753 SmNode *pNode = GetSubNode(i);
01754 pNode->AdaptToY(rDev, nHeight);
01755 pNode->Arrange(rDev, rFormat);
01756 }
01757
01758
01759 long nDist = GetFont().GetSize().Height()
01760 * rFormat.GetDistance(DIS_BRACKETSPACE) / 100L;
01761
01762 SmNode *pLeft = GetSubNode(0);
01763 SmRect::operator = (*pLeft);
01764 for (i = 1; i < nNumSubNodes; i++)
01765 {
01766 BOOL bIsSeparator = i % 2 != 0;
01767 RectVerAlign eVerAlign = bIsSeparator ? RVA_CENTERY : RVA_BASELINE;
01768
01769 SmNode *pRight = GetSubNode(i);
01770 Point aPosX = pRight->AlignTo(*pLeft, RP_RIGHT, RHA_CENTER, eVerAlign),
01771 aPosY = pRight->AlignTo(aRefRect, RP_RIGHT, RHA_CENTER, eVerAlign);
01772 aPosX.X() += nDist;
01773
01774 pRight->MoveTo(Point(aPosX.X(), aPosY.Y()));
01775 ExtendBy(*pRight, bIsSeparator ? RCP_THIS : RCP_XOR);
01776
01777 pLeft = pRight;
01778 }
01779 }
01780
01781
01782
01783
01784
01785 void SmVerticalBraceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01786 {
01787 SmNode *pBody = GetSubNode(0),
01788 *pBrace = GetSubNode(1),
01789 *pScript = GetSubNode(2);
01790 DBG_ASSERT(pBody, "Sm: NULL pointer!");
01791 DBG_ASSERT(pBrace, "Sm: NULL pointer!");
01792 DBG_ASSERT(pScript, "Sm: NULL pointer!");
01793
01794 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
01795 aTmpDev.SetFont(GetFont());
01796
01797 pBody->Arrange(aTmpDev, rFormat);
01798
01799
01800 pScript->SetSize( Fraction( rFormat.GetRelSize(SIZ_LIMITS), 100 ) );
01801
01802 pBrace ->SetSize( Fraction(3, 2) );
01803
01804 long nItalicWidth = pBody->GetItalicWidth();
01805 if (nItalicWidth > 0)
01806 pBrace->AdaptToX(aTmpDev, nItalicWidth);
01807
01808 pBrace ->Arrange(aTmpDev, rFormat);
01809 pScript->Arrange(aTmpDev, rFormat);
01810
01811
01812 RectPos eRectPos;
01813 long nFontHeight = pBody->GetFont().GetSize().Height();
01814 long nDistBody = nFontHeight * rFormat.GetDistance(DIS_ORNAMENTSIZE),
01815 nDistScript = nFontHeight;
01816 if (GetToken().eType == TOVERBRACE)
01817 {
01818 eRectPos = RP_TOP;
01819 nDistBody = - nDistBody;
01820 nDistScript *= - rFormat.GetDistance(DIS_UPPERLIMIT);
01821 }
01822 else
01823 {
01824 eRectPos = RP_BOTTOM;
01825 nDistScript *= + rFormat.GetDistance(DIS_LOWERLIMIT);
01826 }
01827 nDistBody /= 100L;
01828 nDistScript /= 100L;
01829
01830 Point aPos = pBrace->AlignTo(*pBody, eRectPos, RHA_CENTER, RVA_BASELINE);
01831 aPos.Y() += nDistBody;
01832 pBrace->MoveTo(aPos);
01833
01834 aPos = pScript->AlignTo(*pBrace, eRectPos, RHA_CENTER, RVA_BASELINE);
01835 aPos.Y() += nDistScript;
01836 pScript->MoveTo(aPos);
01837
01838 SmRect::operator = (*pBody);
01839 ExtendBy(*pBrace, RCP_THIS).ExtendBy(*pScript, RCP_THIS);
01840 }
01841
01842
01843
01844
01845
01846 SmNode * SmOperNode::GetSymbol()
01847 {
01848 SmNode *pNode = GetSubNode(0);
01849 DBG_ASSERT(pNode, "Sm: NULL pointer!");
01850
01851 if (pNode->GetType() == NSUBSUP)
01852 pNode = ((SmSubSupNode *) pNode)->GetBody();
01853
01854 DBG_ASSERT(pNode, "Sm: NULL pointer!");
01855 return pNode;
01856 }
01857
01858
01859 long SmOperNode::CalcSymbolHeight(const SmNode &rSymbol,
01860 const SmFormat &rFormat) const
01861
01862 {
01863 long nHeight = GetFont().GetSize().Height();
01864
01865 SmTokenType eTmpType = GetToken().eType;
01866 if (eTmpType == TLIM || eTmpType == TLIMINF || eTmpType == TLIMSUP)
01867 return nHeight;
01868
01869 if (!rFormat.IsTextmode())
01870 {
01871
01872 nHeight += (nHeight * 20L) / 100L;
01873
01874 nHeight += nHeight
01875 * rFormat.GetDistance(DIS_OPERATORSIZE) / 100L;
01876 nHeight = nHeight * 686L / 845L;
01877 }
01878
01879
01880 if (rSymbol.GetToken().eType == TSPECIAL)
01881 nHeight = nHeight * 845L / 686L;
01882
01883 return nHeight;
01884 }
01885
01886
01887 void SmOperNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01888 {
01889 SmNode *pOper = GetSubNode(0);
01890 SmNode *pBody = GetSubNode(1);
01891
01892 DBG_ASSERT(pOper, "Sm: Subnode fehlt");
01893 DBG_ASSERT(pBody, "Sm: Subnode fehlt");
01894
01895 SmNode *pSymbol = GetSymbol();
01896 pSymbol->SetSize(Fraction(CalcSymbolHeight(*pSymbol, rFormat),
01897 pSymbol->GetFont().GetSize().Height()));
01898
01899 pBody->Arrange(rDev, rFormat);
01900 pOper->Arrange(rDev, rFormat);
01901
01902 long nOrigHeight = GetFont().GetSize().Height(),
01903 nDist = nOrigHeight
01904 * rFormat.GetDistance(DIS_OPERATORSPACE) / 100L;
01905
01906 Point aPos = pOper->AlignTo(*pBody, RP_LEFT, RHA_CENTER, RVA_MID);
01907 aPos.X() -= nDist;
01908 pOper->MoveTo(aPos);
01909
01910 SmRect::operator = (*pBody);
01911 ExtendBy(*pOper, RCP_THIS);
01912 }
01913
01914
01915
01916
01917
01918 void SmAlignNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01919
01920 {
01921 DBG_ASSERT(GetNumSubNodes() > 0, "Sm: SubNode fehlt");
01922
01923 SmNode *pNode = GetSubNode(0);
01924
01925 RectHorAlign eHorAlign = RHA_CENTER;
01926 switch (GetToken().eType)
01927 {
01928 case TALIGNL: eHorAlign = RHA_LEFT; break;
01929 case TALIGNC: eHorAlign = RHA_CENTER; break;
01930 case TALIGNR: eHorAlign = RHA_RIGHT; break;
01931 default:
01932 break;
01933 }
01934 SetRectHorAlign(eHorAlign);
01935
01936 pNode->Arrange(rDev, rFormat);
01937
01938 SmRect::operator = (pNode->GetRect());
01939 }
01940
01941
01942
01943
01944
01945 void SmAttributNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
01946 {
01947 SmNode *pAttr = GetSubNode(0),
01948 *pBody = GetSubNode(1);
01949 DBG_ASSERT(pBody, "Sm: Body fehlt");
01950 DBG_ASSERT(pAttr, "Sm: Attribut fehlt");
01951
01952 pBody->Arrange(rDev, rFormat);
01953
01954 if (GetScaleMode() == SCALE_WIDTH)
01955 pAttr->AdaptToX(rDev, pBody->GetItalicWidth());
01956 pAttr->Arrange(rDev, rFormat);
01957
01958
01959 RectVerAlign eVerAlign;
01960 long nDist = 0;
01961 switch (GetToken().eType)
01962 { case TUNDERLINE :
01963 eVerAlign = RVA_ATTRIBUT_LO;
01964 break;
01965 case TOVERSTRIKE :
01966 eVerAlign = RVA_ATTRIBUT_MID;
01967 break;
01968 default :
01969 eVerAlign = RVA_ATTRIBUT_HI;
01970 if (pBody->GetType() == NATTRIBUT)
01971 nDist = GetFont().GetSize().Height()
01972 * rFormat.GetDistance(DIS_ORNAMENTSPACE) / 100L;
01973 }
01974 Point aPos = pAttr->AlignTo(*pBody, RP_ATTRIBUT, RHA_CENTER, eVerAlign);
01975 aPos.Y() -= nDist;
01976 pAttr->MoveTo(aPos);
01977
01978 SmRect::operator = (*pBody);
01979 ExtendBy(*pAttr, RCP_THIS, (BOOL) TRUE);
01980 }
01981
01982
01983
01984
01985
01986
01987
01988 void SmFontNode::CreateTextFromNode(String &rText)
01989 {
01990 switch (GetToken().eType)
01991 {
01992 case TBOLD:
01993 APPEND(rText,"bold ");
01994 break;
01995 case TNBOLD:
01996 APPEND(rText,"nbold ");
01997 break;
01998 case TITALIC:
01999 APPEND(rText,"italic ");
02000 break;
02001 case TNITALIC:
02002 APPEND(rText,"nitalic ");
02003 break;
02004 case TPHANTOM:
02005 APPEND(rText,"phantom ");
02006 break;
02007 case TSIZE:
02008 {
02009 APPEND(rText,"size ");
02010 switch (nSizeType)
02011 {
02012 case FNTSIZ_PLUS:
02013 rText.Append('+');
02014 break;
02015 case FNTSIZ_MINUS:
02016 rText.Append('-');
02017 break;
02018 case FNTSIZ_MULTIPLY:
02019 rText.Append('*');
02020 break;
02021 case FNTSIZ_DIVIDE:
02022 rText.Append('/');
02023 break;
02024 case FNTSIZ_ABSOLUT:
02025 default:
02026 break;
02027 }
02028 rText += String( ::rtl::math::doubleToUString(
02029 static_cast<double>(aFontSize),
02030 rtl_math_StringFormat_Automatic,
02031 rtl_math_DecimalPlaces_Max, '.', sal_True));
02032 rText.Append(' ');
02033 }
02034 break;
02035 case TBLACK:
02036 APPEND(rText,"color black ");
02037 break;
02038 case TWHITE:
02039 APPEND(rText,"color white ");
02040 break;
02041 case TRED:
02042 APPEND(rText,"color red ");
02043 break;
02044 case TGREEN:
02045 APPEND(rText,"color green ");
02046 break;
02047 case TBLUE:
02048 APPEND(rText,"color blue ");
02049 break;
02050 case TCYAN:
02051 APPEND(rText,"color cyan ");
02052 break;
02053 case TMAGENTA:
02054 APPEND(rText,"color magenta ");
02055 break;
02056 case TYELLOW:
02057 APPEND(rText,"color yellow ");
02058 break;
02059 case TSANS:
02060 APPEND(rText,"font sans ");
02061 break;
02062 case TSERIF:
02063 APPEND(rText,"font serif ");
02064 break;
02065 case TFIXED:
02066 APPEND(rText,"font fixed ");
02067 break;
02068 default:
02069 break;
02070 }
02071 GetSubNode(1)->CreateTextFromNode(rText);
02072 }
02073
02074
02075 void SmFontNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
02076 {
02078 SmNode::Prepare(rFormat, rDocShell);
02079
02080 int nFnt = -1;
02081 switch (GetToken().eType)
02082 {
02083 case TFIXED: nFnt = FNT_FIXED; break;
02084 case TSANS: nFnt = FNT_SANS; break;
02085 case TSERIF: nFnt = FNT_SERIF; break;
02086 default:
02087 break;
02088 }
02089 if (nFnt != -1)
02090 { GetFont() = rFormat.GetFont( sal::static_int_cast< USHORT >(nFnt) );
02091 SetFont(GetFont());
02092 }
02093
02096 Flags() |= FLG_FONT;
02097 }
02098
02099
02100 void SmFontNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02101 {
02102 SmNode *pNode = GetSubNode(1);
02103 DBG_ASSERT(pNode, "Sm: SubNode fehlt");
02104
02105 switch (GetToken().eType)
02106 { case TSIZE :
02107 pNode->SetFontSize(aFontSize, nSizeType);
02108 break;
02109 case TSANS :
02110 case TSERIF :
02111 case TFIXED :
02112 pNode->SetFont(GetFont());
02113 break;
02114 case TUNKNOWN : break;
02115
02116 case TPHANTOM : SetPhantom(TRUE); break;
02117 case TBOLD : SetAttribut(ATTR_BOLD); break;
02118 case TITALIC : SetAttribut(ATTR_ITALIC); break;
02119 case TNBOLD : ClearAttribut(ATTR_BOLD); break;
02120 case TNITALIC : ClearAttribut(ATTR_ITALIC); break;
02121
02122 case TBLACK : SetColor(Color(COL_BLACK)); break;
02123 case TWHITE : SetColor(Color(COL_WHITE)); break;
02124 case TRED : SetColor(Color(COL_RED)); break;
02125 case TGREEN : SetColor(Color(COL_GREEN)); break;
02126 case TBLUE : SetColor(Color(COL_BLUE)); break;
02127 case TCYAN : SetColor(Color(COL_CYAN)); break;
02128 case TMAGENTA : SetColor(Color(COL_MAGENTA)); break;
02129 case TYELLOW : SetColor(Color(COL_YELLOW)); break;
02130
02131 default:
02132 DBG_ASSERT(FALSE, "Sm: unbekannter Fall");
02133 }
02134
02135 pNode->Arrange(rDev, rFormat);
02136
02137 SmRect::operator = (pNode->GetRect());
02138 }
02139
02140
02141 void SmFontNode::SetSizeParameter(const Fraction& rValue, USHORT Type)
02142 {
02143 nSizeType = Type;
02144 aFontSize = rValue;
02145 }
02146
02147
02148
02149
02150
02151 SmPolyLineNode::SmPolyLineNode(const SmToken &rNodeToken)
02152 : SmGraphicNode(NPOLYLINE, rNodeToken)
02153 {
02154 aPoly.SetSize(2);
02155 nWidth = 0;
02156 }
02157
02158
02159 void SmPolyLineNode::AdaptToX(const OutputDevice &, ULONG nNewWidth)
02160 {
02161 aToSize.Width() = nNewWidth;
02162 }
02163
02164
02165 void SmPolyLineNode::AdaptToY(const OutputDevice &, ULONG nNewHeight)
02166 {
02167 GetFont().FreezeBorderWidth();
02168 aToSize.Height() = nNewHeight;
02169 }
02170
02171
02172 void SmPolyLineNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02173 {
02177 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02178 aTmpDev.SetFont(GetFont());
02179
02180 long nBorderwidth = GetFont().GetBorderWidth();
02181
02182
02183
02184
02185 DBG_ASSERT(aPoly.GetSize() == 2, "Sm : falsche Anzahl von Punkten");
02186 Point aPointA, aPointB;
02187 if (GetToken().eType == TWIDESLASH)
02188 {
02189 aPointA.X() = nBorderwidth;
02190 aPointA.Y() = aToSize.Height() - nBorderwidth;
02191 aPointB.X() = aToSize.Width() - nBorderwidth;
02192 aPointB.Y() = nBorderwidth;
02193 }
02194 else
02195 {
02196 DBG_ASSERT(GetToken().eType == TWIDEBACKSLASH, "Sm : unerwartetes Token");
02197 aPointA.X() =
02198 aPointA.Y() = nBorderwidth;
02199 aPointB.X() = aToSize.Width() - nBorderwidth;
02200 aPointB.Y() = aToSize.Height() - nBorderwidth;
02201 }
02202 aPoly.SetPoint(aPointA, 0);
02203 aPoly.SetPoint(aPointB, 1);
02204
02205 long nThick = GetFont().GetSize().Height()
02206 * rFormat.GetDistance(DIS_STROKEWIDTH) / 100L;
02207 nWidth = nThick + 2 * nBorderwidth;
02208
02209 SmRect::operator = (SmRect(aToSize.Width(), aToSize.Height()));
02210 }
02211
02212
02213 void SmPolyLineNode::Draw(OutputDevice &rDev, const Point &rPosition) const
02214 {
02215 if (IsPhantom())
02216 return;
02217
02218 long nBorderwidth = GetFont().GetBorderWidth();
02219
02220 LineInfo aInfo;
02221 aInfo.SetWidth(nWidth - 2 * nBorderwidth);
02222
02223 Point aOffset (Point() - aPoly.GetBoundRect().TopLeft()
02224 + Point(nBorderwidth, nBorderwidth)),
02225 aPos (rPosition + aOffset);
02226 ((Polygon &) aPoly).Move(aPos.X(), aPos.Y());
02227
02228 SmTmpDevice aTmpDev ((OutputDevice &) rDev, FALSE);
02229 aTmpDev.SetLineColor( GetFont().GetColor() );
02230
02231 rDev.DrawPolyLine(aPoly, aInfo);
02232
02233 #ifdef SM_RECT_DEBUG
02234 if (!IsDebug())
02235 return;
02236
02237 int nRFlags = SM_RECT_CORE | SM_RECT_ITALIC | SM_RECT_LINES | SM_RECT_MID;
02238 SmRect::Draw(rDev, rPosition, nRFlags);
02239 #endif
02240 }
02241
02242
02243
02244
02245 void SmRootSymbolNode::AdaptToX(const OutputDevice &, ULONG nWidth)
02246 {
02247 nBodyWidth = nWidth;
02248 }
02249
02250
02251 void SmRootSymbolNode::AdaptToY(const OutputDevice &rDev, ULONG nHeight)
02252 {
02253
02254
02255 SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / 10L);
02256 }
02257
02258
02259 void SmRootSymbolNode::Draw(OutputDevice &rDev, const Point &rPosition) const
02260 {
02261 if (IsPhantom())
02262 return;
02263
02264
02265 SmMathSymbolNode::Draw(rDev, rPosition);
02266
02267 SmTmpDevice aTmpDev( (OutputDevice &) rDev, TRUE );
02268 aTmpDev.SetFillColor(GetFont().GetColor());
02269 rDev.SetLineColor();
02270 aTmpDev.SetFont( GetFont() );
02271
02272
02273
02274
02275
02276 long nBarHeight = GetWidth() * 7L / 100L;
02277 long nBarWidth = nBodyWidth + GetBorderWidth();
02278 Point aBarOffset( GetWidth(), +GetBorderWidth() );
02279 Point aBarPos( rPosition + aBarOffset );
02280
02281 Rectangle aBar(aBarPos, Size( nBarWidth, nBarHeight) );
02284
02285
02286 Point aDrawPos( rDev.PixelToLogic(rDev.LogicToPixel(aBar.TopLeft())) );
02287
02288 aBar.SetPos( aDrawPos );
02289
02290 rDev.DrawRect( aBar );
02291
02292 #ifdef SM_RECT_DEBUG
02293 if (!IsDebug())
02294 return;
02295
02296 int nRFlags = SM_RECT_CORE | SM_RECT_ITALIC | SM_RECT_LINES | SM_RECT_MID;
02297 SmRect::Draw(rDev, rPosition, nRFlags);
02298 #endif
02299 }
02300
02301
02302
02303
02304
02305 void SmRectangleNode::AdaptToX(const OutputDevice &, ULONG nWidth)
02306 {
02307 aToSize.Width() = nWidth;
02308 }
02309
02310
02311 void SmRectangleNode::AdaptToY(const OutputDevice &, ULONG nHeight)
02312 {
02313 GetFont().FreezeBorderWidth();
02314 aToSize.Height() = nHeight;
02315 }
02316
02317
02318 void SmRectangleNode::Arrange(const OutputDevice &rDev, const SmFormat &)
02319 {
02320 long nFontHeight = GetFont().GetSize().Height();
02321 long nWidth = aToSize.Width(),
02322 nHeight = aToSize.Height();
02323 if (nHeight == 0)
02324 nHeight = nFontHeight / 30;
02325 if (nWidth == 0)
02326 nWidth = nFontHeight / 3;
02327
02328 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02329 aTmpDev.SetFont(GetFont());
02330
02331
02332 ULONG nTmpBorderWidth = GetFont().GetBorderWidth();
02333
02334 nHeight += 2 * nTmpBorderWidth;
02335
02338 SmRect::operator = (SmRect(nWidth, nHeight));
02339 }
02340
02341
02342 void SmRectangleNode::Draw(OutputDevice &rDev, const Point &rPosition) const
02343 {
02344 if (IsPhantom())
02345 return;
02346
02347 SmTmpDevice aTmpDev ((OutputDevice &) rDev, FALSE);
02348 aTmpDev.SetFillColor(GetFont().GetColor());
02349 rDev.SetLineColor();
02350 aTmpDev.SetFont(GetFont());
02351
02352 ULONG nTmpBorderWidth = GetFont().GetBorderWidth();
02353
02354
02355 Rectangle aTmp (AsRectangle() + rPosition - GetTopLeft());
02356 aTmp.Left() += nTmpBorderWidth;
02357 aTmp.Right() -= nTmpBorderWidth;
02358 aTmp.Top() += nTmpBorderWidth;
02359 aTmp.Bottom() -= nTmpBorderWidth;
02360
02361 DBG_ASSERT(aTmp.GetHeight() > 0 && aTmp.GetWidth() > 0,
02362 "Sm: leeres Rechteck");
02363
02366
02367
02368 Point aPos (rDev.PixelToLogic(rDev.LogicToPixel(aTmp.TopLeft())));
02369 aTmp.SetPos(aPos);
02370
02371 rDev.DrawRect(aTmp);
02372
02373 #ifdef SM_RECT_DEBUG
02374 if (!IsDebug())
02375 return;
02376
02377 int nRFlags = SM_RECT_CORE | SM_RECT_ITALIC | SM_RECT_LINES | SM_RECT_MID;
02378 SmRect::Draw(rDev, rPosition, nRFlags);
02379 #endif
02380 }
02381
02382
02383
02384
02385
02386 void SmTextNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
02387 {
02388 SmNode::Prepare(rFormat, rDocShell);
02389
02390
02391
02392
02393 if (TTEXT == GetToken().eType)
02394 SetRectHorAlign( RHA_LEFT );
02395
02396 aText = GetToken().aText;
02397 GetFont() = rFormat.GetFont(GetFontDesc());
02398
02399 if (IsItalic( GetFont() ))
02400 Attributes() |= ATTR_ITALIC;
02401 if (IsBold( GetFont() ))
02402 Attributes() |= ATTR_BOLD;
02403
02404 };
02405
02406
02407 void SmTextNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02408 {
02409 PrepareAttributes();
02410
02411 USHORT nSizeDesc = GetFontDesc() == FNT_FUNCTION ?
02412 SIZ_FUNCTION : SIZ_TEXT;
02413 GetFont() *= Fraction (rFormat.GetRelSize(nSizeDesc), 100);
02414
02415 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02416 aTmpDev.SetFont(GetFont());
02417
02418 SmRect::operator = (SmRect(aTmpDev, &rFormat, aText, GetFont().GetBorderWidth()));
02419 }
02420
02421 void SmTextNode::CreateTextFromNode(String &rText)
02422 {
02423 BOOL bQuoted=FALSE;
02424 if (GetToken().eType == TTEXT)
02425 {
02426 rText.Append('\"');
02427 bQuoted=TRUE;
02428 }
02429 else
02430 {
02431 SmParser aParseTest;
02432 SmNode *pTable = aParseTest.Parse(GetToken().aText);
02433 bQuoted=TRUE;
02434 if ( (pTable->GetType() == NTABLE) && (pTable->GetNumSubNodes() == 1) )
02435 {
02436 SmNode *pResult = pTable->GetSubNode(0);
02437 if ( (pResult->GetType() == NLINE) &&
02438 (pResult->GetNumSubNodes() == 1) )
02439 {
02440 pResult = pResult->GetSubNode(0);
02441 if ( (pResult->GetType() == NEXPRESSION) &&
02442 (pResult->GetNumSubNodes() == 1) )
02443 {
02444 pResult = pResult->GetSubNode(0);
02445 if (pResult->GetType() == NTEXT)
02446 bQuoted=FALSE;
02447 }
02448 }
02449 }
02450 delete pTable;
02451
02452 if ((GetToken().eType == TIDENT) && (GetFontDesc() == FNT_FUNCTION))
02453 {
02454
02455 APPEND(rText,"func ");
02456 }
02457 else if (bQuoted)
02458 APPEND(rText,"italic ");
02459
02460 if (bQuoted)
02461 rText.Append('\"');
02462
02463 }
02464
02465 rText.Append(GetToken().aText);
02466
02467 if (bQuoted)
02468 rText.Append('\"');
02469 rText.Append(' ');
02470 }
02471
02472 void SmTextNode::Draw(OutputDevice &rDev, const Point& rPosition) const
02473 {
02474 if (IsPhantom() || aText.Len() == 0 || aText.GetChar(0) == xub_Unicode('\0'))
02475 return;
02476
02477 SmTmpDevice aTmpDev ((OutputDevice &) rDev, FALSE);
02478 aTmpDev.SetFont(GetFont());
02479
02480 Point aPos (rPosition);
02481 aPos.Y() += GetBaselineOffset();
02482
02483 aPos = rDev.PixelToLogic( rDev.LogicToPixel(aPos) );
02484
02485 rDev.DrawStretchText(aPos, GetWidth(), aText);
02486
02487 #ifdef SM_RECT_DEBUG
02488 if (!IsDebug())
02489 return;
02490
02491 int nRFlags = SM_RECT_CORE | SM_RECT_ITALIC | SM_RECT_LINES | SM_RECT_MID;
02492 SmRect::Draw(rDev, rPosition, nRFlags);
02493 #endif
02494 }
02495
02496 void SmTextNode::GetAccessibleText( String &rText ) const
02497 {
02498 rText += aText;
02499 }
02500
02501
02502
02503 void SmMatrixNode::CreateTextFromNode(String &rText)
02504 {
02505 APPEND(rText,"matrix {");
02506 for (USHORT i = 0; i < nNumRows; i++)
02507 {
02508 for (USHORT j = 0; j < nNumCols; j++)
02509 {
02510 SmNode *pNode = GetSubNode(i * nNumCols + j);
02511 pNode->CreateTextFromNode(rText);
02512 if (j != nNumCols-1)
02513 APPEND(rText,"# ");
02514 }
02515 if (i != nNumRows-1)
02516 APPEND(rText,"## ");
02517 }
02518 rText.EraseTrailingChars();
02519 APPEND(rText,"} ");
02520 }
02521
02522
02523 void SmMatrixNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02524 {
02525 Point aPosition,
02526 aOffset;
02527 SmNode *pNode;
02528 USHORT i, j;
02529
02530
02531
02532 long *pColWidth = new long[nNumCols];
02533 for (j = 0; j < nNumCols; j++)
02534 pColWidth[j] = 0;
02535
02536
02537 USHORT nNodes = GetNumSubNodes();
02538 for (i = 0; i < nNodes; i++)
02539 {
02540 USHORT nIdx = nNodes - 1 - i;
02541 if (NULL != (pNode = GetSubNode(nIdx)))
02542 {
02543 pNode->Arrange(rDev, rFormat);
02544 int nCol = nIdx % nNumCols;
02545 pColWidth[nCol] = Max(pColWidth[nCol], pNode->GetItalicWidth());
02546 }
02547 }
02548
02549
02550 const int nNormDist = 3 * GetFont().GetSize().Height();
02551
02552
02553
02554 long nHorDist = nNormDist * rFormat.GetDistance(DIS_MATRIXCOL) / 100L,
02555 nVerDist = nNormDist * rFormat.GetDistance(DIS_MATRIXROW) / 100L;
02556
02557
02558 long *pColLeft = new long[nNumCols];
02559 long nX = 0;
02560 for (j = 0; j < nNumCols; j++)
02561 { pColLeft[j] = nX;
02562 nX += pColWidth[j] + nHorDist;
02563 }
02564
02565 Point aPos, aDelta;
02566 SmRect aLineRect;
02567 SmRect::operator = (SmRect());
02568 for (i = 0; i < nNumRows; i++)
02569 { aLineRect = SmRect();
02570 for (j = 0; j < nNumCols; j++)
02571 { SmNode *pTmpNode = GetSubNode(i * nNumCols + j);
02572 DBG_ASSERT(pTmpNode, "Sm: NULL pointer");
02573
02574 const SmRect &rNodeRect = pTmpNode->GetRect();
02575
02576
02577 aPos = rNodeRect.AlignTo(aLineRect, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
02578 aPos.X() += nHorDist;
02579
02580
02581 const SmNode *pCoNode = pTmpNode->GetLeftMost();
02582 RectHorAlign eHorAlign = pCoNode->GetRectHorAlign();
02583
02584
02585
02586 switch (eHorAlign)
02587 { case RHA_LEFT:
02588 aPos.X() = rNodeRect.GetLeft() + pColLeft[j];
02589 break;
02590 case RHA_CENTER:
02591 aPos.X() = rNodeRect.GetLeft() + pColLeft[j]
02592 + pColWidth[j] / 2
02593 - rNodeRect.GetItalicCenterX();
02594 break;
02595 case RHA_RIGHT:
02596 aPos.X() = rNodeRect.GetLeft() + pColLeft[j]
02597 + pColWidth[j] - rNodeRect.GetItalicWidth();
02598 break;
02599 }
02600
02601 pTmpNode->MoveTo(aPos);
02602 aLineRect.ExtendBy(rNodeRect, RCP_XOR);
02603 }
02604
02605 aPos = aLineRect.AlignTo(*this, RP_BOTTOM, RHA_CENTER, RVA_BASELINE);
02606 aPos.Y() += nVerDist;
02607
02608
02609 aDelta.X() = 0;
02610 aDelta.Y() = aPos.Y() - aLineRect.GetTop();
02611 aLineRect.Move(aDelta);
02612 for (j = 0; j < nNumCols; j++)
02613 if (NULL != (pNode = GetSubNode(i * nNumCols + j)))
02614 pNode->Move(aDelta);
02615
02616 ExtendBy(aLineRect, RCP_NONE);
02617 }
02618
02619 delete [] pColLeft;
02620 delete [] pColWidth;
02621 }
02622
02623
02624 void SmMatrixNode::SetRowCol(USHORT nMatrixRows, USHORT nMatrixCols)
02625 {
02626 nNumRows = nMatrixRows;
02627 nNumCols = nMatrixCols;
02628 }
02629
02630
02631 SmNode * SmMatrixNode::GetLeftMost()
02632 {
02633 return this;
02634 }
02635
02636
02637
02638
02639
02640 SmMathSymbolNode::SmMathSymbolNode(const SmToken &rNodeToken)
02641 : SmSpecialNode(NMATH, rNodeToken, FNT_MATH)
02642 {
02643 xub_Unicode cChar = GetToken().cMathChar;
02644 if ((xub_Unicode) '\0' != cChar)
02645 SetText( cChar );
02646 }
02647
02648 void SmMathSymbolNode::AdaptToX(const OutputDevice &rDev, ULONG nWidth)
02649 {
02650
02651 Size aFntSize (GetFont().GetSize());
02652
02654 aFntSize.Width() = nWidth;
02655 GetFont().SetSize(aFntSize);
02656
02657 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02658 aTmpDev.SetFont(GetFont());
02659
02660
02661 long nTmpBorderWidth = GetFont().GetBorderWidth();
02662 long nDenom = SmRect(aTmpDev, NULL, GetText(), nTmpBorderWidth).GetItalicWidth();
02663
02664
02665 aFntSize.Width() *= nWidth;
02666 aFntSize.Width() /= nDenom ? nDenom : 1;
02667
02668 GetFont().SetSize(aFntSize);
02669 }
02670
02671 void SmMathSymbolNode::AdaptToY(const OutputDevice &rDev, ULONG nHeight)
02672 {
02673 GetFont().FreezeBorderWidth();
02674 Size aFntSize (GetFont().GetSize());
02675
02676
02677
02678 if (aFntSize.Width() == 0)
02679 {
02680 OutputDevice &rDevNC = (OutputDevice &) rDev;
02681 rDevNC.Push(PUSH_FONT | PUSH_MAPMODE);
02682 rDevNC.SetFont(GetFont());
02683 aFntSize.Width() = rDev.GetFontMetric().GetSize().Width();
02684 rDevNC.Pop();
02685 }
02686 DBG_ASSERT(aFntSize.Width() != 0, "Sm: ");
02687
02690 aFntSize.Height() = nHeight;
02691 GetFont().SetSize(aFntSize);
02692
02693 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02694 aTmpDev.SetFont(GetFont());
02695
02696
02697 long nTmpBorderWidth = GetFont().GetBorderWidth();
02698 long nDenom = SmRect(aTmpDev, NULL, GetText(), nTmpBorderWidth).GetHeight();
02699
02700
02701 aFntSize.Height() *= nHeight;
02702 aFntSize.Height() /= nDenom ? nDenom : 1;
02703
02704 GetFont().SetSize(aFntSize);
02705 }
02706
02707
02708 void SmMathSymbolNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
02709 {
02710 SmNode::Prepare(rFormat, rDocShell);
02711
02712 DBG_ASSERT(GetFont().GetCharSet() == RTL_TEXTENCODING_SYMBOL ||
02713 GetFont().GetCharSet() == RTL_TEXTENCODING_UNICODE,
02714 "incorrect charset for character from StarMath/StarSymbol font");
02715
02716 Flags() |= FLG_FONT | FLG_ITALIC;
02717 };
02718
02719
02720 void SmMathSymbolNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02721 {
02722 const XubString &rText = GetText();
02723
02724 if (rText.Len() == 0 || rText.GetChar(0) == xub_Unicode('\0'))
02725 { SmRect::operator = (SmRect());
02726 return;
02727 }
02728
02729 PrepareAttributes();
02730
02731 GetFont() *= Fraction (rFormat.GetRelSize(SIZ_TEXT), 100);
02732
02733 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02734 aTmpDev.SetFont(GetFont());
02735
02736 SmRect::operator = (SmRect(aTmpDev, &rFormat, rText, GetFont().GetBorderWidth()));
02737 }
02738
02739 void SmMathSymbolNode::CreateTextFromNode(String &rText)
02740 {
02741 String sStr;
02742 MathType::LookupChar(GetToken().cMathChar, sStr);
02743 rText.Append(sStr);
02744 }
02745
02746 void SmRectangleNode::CreateTextFromNode(String &rText)
02747 {
02748 switch (GetToken().eType)
02749 {
02750 case TUNDERLINE:
02751 APPEND(rText,"underline ");
02752 break;
02753 case TOVERLINE:
02754 APPEND(rText,"overline ");
02755 break;
02756 case TOVERSTRIKE:
02757 APPEND(rText,"overstrike ");
02758 break;
02759 default:
02760 break;
02761 }
02762 }
02763
02764 void SmAttributNode::CreateTextFromNode(String &rText)
02765 {
02766 SmNode *pNode;
02767 USHORT nSize = GetNumSubNodes();
02768 DBG_ASSERT(nSize == 2, "Node missing members");
02769 rText.Append('{');
02770 sal_Unicode nLast=0;
02771 if (NULL != (pNode = GetSubNode(0)))
02772 {
02773 String aStr;
02774 pNode->CreateTextFromNode(aStr);
02775 if (aStr.Len() > 1)
02776 rText.Append(aStr);
02777 else
02778 {
02779 nLast = aStr.GetChar(0);
02780 switch (nLast)
02781 {
02782 case 0xAF:
02783 APPEND(rText,"overline ");
02784 break;
02785 case 0x2d9:
02786 APPEND(rText,"dot ");
02787 break;
02788 case 0x2dc:
02789 APPEND(rText,"widetilde ");
02790 break;
02791 case 0xA8:
02792 APPEND(rText,"ddot ");
02793 break;
02794 case 0xE082:
02795 break;
02796 case 0xE09B:
02797 APPEND(rText,"dddot ");
02798 break;
02799 default:
02800 rText.Append(nLast);
02801 break;
02802 }
02803 }
02804 }
02805
02806 if (nSize == 2)
02807 if (NULL != (pNode = GetSubNode(1)))
02808 pNode->CreateTextFromNode(rText);
02809
02810 rText.EraseTrailingChars();
02811
02812 if (nLast == 0xE082)
02813 APPEND(rText," overbrace {}");
02814
02815 APPEND(rText,"} ");
02816 }
02817
02818
02819
02820
02821 void SmSpecialNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
02822 {
02823 SmNode::Prepare(rFormat, rDocShell);
02824
02825 const SmSym *pSym;
02826 SmModule *pp = SM_MOD1();
02827
02828 if (NULL != (pSym = pp->GetSymSetManager().GetSymbolByName(GetToken().aText)))
02829 {
02830 SetText( pSym->GetCharacter() );
02831 GetFont() = pSym->GetFace();
02832 }
02833 else
02834 {
02835 SetText( GetToken().aText );
02836 GetFont() = rFormat.GetFont(FNT_VARIABLE);
02837 }
02838
02839 GetFont().SetSize( rFormat.GetFont( FNT_VARIABLE ).GetSize() );
02840
02846
02848 if (IsItalic( GetFont() ))
02849 SetAttribut(ATTR_ITALIC);
02850 if (IsBold( GetFont() ))
02851 SetAttribut(ATTR_BOLD);
02852
02853 Flags() |= FLG_FONT;
02854 };
02855
02856
02857 void SmSpecialNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02858 {
02859 PrepareAttributes();
02860
02861 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02862 aTmpDev.SetFont(GetFont());
02863
02864 SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(), GetFont().GetBorderWidth()));
02865 }
02866
02867
02868 void SmSpecialNode::Draw(OutputDevice &rDev, const Point& rPosition) const
02869 {
02872 ((SmSpecialNode *)this)->GetFont().SetAlign(ALIGN_BASELINE);
02873
02874 SmTextNode::Draw(rDev, rPosition);
02875 }
02876
02877
02878
02879
02880
02881 void SmGlyphSpecialNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02882 {
02883 PrepareAttributes();
02884
02885 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02886 aTmpDev.SetFont(GetFont());
02887
02888 SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(),
02889 GetFont().GetBorderWidth()).AsGlyphRect());
02890 }
02891
02892
02893
02894
02895
02896 void SmPlaceNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
02897 {
02898 SmNode::Prepare(rFormat, rDocShell);
02899
02900 GetFont().SetColor(COL_GRAY);
02901 Flags() |= FLG_COLOR | FLG_FONT | FLG_ITALIC;
02902 };
02903
02904
02905 void SmPlaceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02906 {
02907 PrepareAttributes();
02908
02909 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02910 aTmpDev.SetFont(GetFont());
02911
02912 SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(), GetFont().GetBorderWidth()));
02913 }
02914
02915
02916
02917
02918
02919 void SmErrorNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
02920 {
02921 SmNode::Prepare(rFormat, rDocShell);
02922
02923 GetFont().SetColor(COL_RED);
02924 Flags() |= FLG_VISIBLE | FLG_BOLD | FLG_ITALIC
02925 | FLG_COLOR | FLG_FONT | FLG_SIZE;
02926 }
02927
02928
02929 void SmErrorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02930 {
02931 PrepareAttributes();
02932
02933 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02934 aTmpDev.SetFont(GetFont());
02935
02936 const XubString &rText = GetText();
02937 SmRect::operator = (SmRect(aTmpDev, &rFormat, rText, GetFont().GetBorderWidth()));
02938 }
02939
02940
02941
02942
02943
02944 void SmBlankNode::IncreaseBy(const SmToken &rToken)
02945 {
02946 switch(rToken.eType)
02947 {
02948 case TBLANK: nNum += 4; break;
02949 case TSBLANK: nNum += 1; break;
02950 default:
02951 break;
02952 }
02953 }
02954
02955
02956 void SmBlankNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
02957 {
02958 SmNode::Prepare(rFormat, rDocShell);
02959
02963 GetFont() = rFormat.GetFont(FNT_VARIABLE);
02964
02965 Flags() |= FLG_FONT | FLG_BOLD | FLG_ITALIC;
02966 }
02967
02968
02969 void SmBlankNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
02970 {
02971 SmTmpDevice aTmpDev ((OutputDevice &) rDev, TRUE);
02972 aTmpDev.SetFont(GetFont());
02973
02974
02975
02976 long nDist = GetFont().GetSize().Height() / 10L,
02977 nSpace = nNum * nDist;
02978
02979
02980 SmRect::operator = (SmRect(aTmpDev, &rFormat, XubString(xub_Unicode(' ')),
02981 GetFont().GetBorderWidth()));
02982
02983
02984 SetItalicSpaces(0, 0);
02985 SetWidth(nSpace);
02986 }
02987
02988
02989