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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include "camtypes.h"
00104 #include "cdrfiltr.h"
00105 #include "nodetxts.h"
00106 #include "nodetxtl.h"
00107 #include "nodetext.h"
00108
00109
00110
00111 #include "fontman.h"
00112
00113 DECLARE_SOURCE("$Revision: 1282 $");
00114
00115 #define new CAM_DEBUG_NEW
00116
00117 static TCHAR *CDRDefaultFontName = "AvantGarde Bk BT";
00118 static CDRTextStyle CDRDefaultTextStyle = {0, (72000*24)/72, FALSE, FALSE, FALSE, CDRSCRIPT_NONE,
00119 (1000*24)/72, 100, JLEFT};
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 BOOL CDRFilter::ConvertText(cdrfOffsetHeader *Header)
00137 {
00138
00139 if(FindDataInObject(Header, cdrfOBJOFFSETTYPE_PATHTEXT1) != 0
00140 && FindDataInObject(Header, cdrfOBJOFFSETTYPE_PATHTEXT2) != 0)
00141 {
00142 IsTextOnAPath = TRUE;
00143 }
00144 else
00145 {
00146 IsTextOnAPath = FALSE;
00147 }
00148
00149
00150 IsText = TRUE;
00151 IsTextStory = FALSE;
00152
00153
00154 if(Version == CDRVERSION_3)
00155 return ConvertText3(Header);
00156
00157 if(Version == CDRVERSION_4)
00158 {
00159 if(CDRDATA_WORD(Header->ObjectType) == cdrfOBJTYPE_TEXT)
00160 {
00161 return ConvertText4Art(Header);
00162 }
00163 else
00164 {
00165 return ConvertText4Para(Header);
00166 }
00167 }
00168
00169
00170 INT32 FrameX = 0, FrameY = 0;
00171 DocCoord Trans = DocCoord(0,0);
00172 if(Header->ObjectType == cdrfOBJTYPE_TEXTSTORY)
00173 {
00174
00175 cdrfTextStoryCoordData *Coords = (cdrfTextStoryCoordData *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
00176
00177 if(Coords == 0)
00178 {
00179 FormatError = TRUE;
00180 return TRUE;
00181 }
00182
00183 FrameX = CDRDATA_WORD(Coords->XSize);
00184 FrameY = CDRDATA_WORD(Coords->YSize);
00185 TRACEUSER( "Ben", _T("Initial frame dimensions: X = %d Y = %d\n"), FrameX, FrameY);
00186
00187 IsTextStory = TRUE;
00188 }
00189 else
00190 {
00191 IsTextStory = FALSE;
00192 }
00193
00194
00195
00196
00197
00198
00199 ERROR3IF(RIFF->GetObjType() != RIFFOBJECTTYPE_CHUNK || RIFF->GetObjChunkType() != cdrT_loda,
00200 "CDFFilter::ConvertText called with RIFF on a non-loda chunk");
00201 UINT32 EndLevel = RIFF->GetObjLevel() - 1;
00202
00203
00204
00205 BOOL Found = FALSE;
00206 do
00207 {
00208 if(RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK && RIFF->GetObjChunkType() == cdrT_txsm)
00209 {
00210
00211 Found = TRUE;
00212 }
00213 else if(RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART && RIFF->GetObjChunkType() == cdrT_trfl)
00214 {
00215
00216 if(!RIFF->GetListContents(&TransformChunk, &TransformChunkSize))
00217 return FALSE;
00218 }
00219
00220 UpdateProgress();
00221
00222 if(!Found)
00223 if(!RIFF->NextObject())
00224 return FALSE;
00225
00226 } while(Found == FALSE && (RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() >= EndLevel));
00227
00228 if(RIFF->GetObjType() != RIFFOBJECTTYPE_CHUNK || RIFF->GetObjChunkType() != cdrT_txsm)
00229 {
00230 FormatError = TRUE;
00231 return TRUE;
00232 }
00233
00234
00235 INT32 TextInfoSize = RIFF->GetObjSize();
00236
00237
00238 if(!RIFF->AquireChunkData())
00239 return FALSE;
00240
00241
00242 ADDR TextInfo;
00243 if((TextInfo = RIFF->GetAquiredData()) == 0)
00244 {
00245 return FALSE;
00246 }
00247 cdrfTextInfoHdr *TIH = (cdrfTextInfoHdr *)TextInfo;
00248
00249
00250 TextStory *TSNode = new TextStory;
00251
00252 if(TSNode == 0)
00253 return FALSE;
00254
00255
00256 UINT32 NParagraphs = CDRDATA_WORD(TIH->NParagraphs);
00257
00258
00259 INT32 Loc = sizeof(cdrfTextInfoHdr);
00260 INT32 FirstLineSpace = -1;
00261 INT32 InitialFirstLineSpace = -1;
00262 INT32 ThisLineSpace = 0;
00263 INT32 PreviousLineSpace = 0;
00264 INT32 MaximumLineX = 0;
00265 INT32 Lines = 1;
00266 Justification Just;
00267
00268
00269 UINT32 CurrentPara;
00270 INT32 LineX;
00271 for(CurrentPara = 0; CurrentPara < NParagraphs; CurrentPara++)
00272 {
00273
00274 LineX = 0;
00275
00276
00277 if((Loc + (INT32)sizeof(cdrfTextInfoParaHdr)) > TextInfoSize)
00278 break;
00279
00280
00281 cdrfTextInfoParaHdr *ParaHdr = (cdrfTextInfoParaHdr *)(TextInfo + Loc);
00282 Loc += sizeof(cdrfTextInfoParaHdr);
00283
00284
00285 INT32 NFontDefns = CDRDATA_WORD(ParaHdr->NFontDefns);
00286
00287 if((Loc + ((INT32)sizeof(cdrfTextInfoFontDefn) * NFontDefns)) > TextInfoSize)
00288 break;
00289
00290 cdrfTextInfoFontDefn *FontDefns = (cdrfTextInfoFontDefn *)(TextInfo + Loc);
00291 Loc += (sizeof(cdrfTextInfoFontDefn) * NFontDefns);
00292
00293
00294 if(NFontDefns <= 0)
00295 break;
00296
00297 CDRTextStyle *Styles = new CDRTextStyle[NFontDefns];
00298
00299
00300 if(!GetTextStyleFromCDRStyle(&Styles[0], ParaHdr->Style))
00301 goto NoMemory;
00302
00303
00304 Just = Styles[0].Just;
00305
00306
00307 PreviousLineSpace = (Styles[0].FontSize * 12) / 10;
00308
00309
00310 for(INT32 l = 1; l < NFontDefns; l++)
00311 {
00312 if(!GetTextStyleFromDefn(&Styles[l], &FontDefns[l], &Styles[0]))
00313 return FALSE;
00314 }
00315
00316
00317 if((Loc + (INT32)sizeof(cdrfTextInfoParaInfo)) > TextInfoSize)
00318 break;
00319
00320 cdrfTextInfoParaInfo *PInfo = (cdrfTextInfoParaInfo *)(TextInfo + Loc);
00321
00322 Loc += sizeof(cdrfTextInfoParaInfo);
00323
00324 INT32 NChars = CDRDATA_WORD(PInfo->NChars);
00325
00326
00327 if((Loc + ((INT32)sizeof(cdrfTextInfoChar) * NChars)) > TextInfoSize)
00328 break;
00329
00330 cdrfTextInfoChar *Chars = (cdrfTextInfoChar *)(TextInfo + Loc);
00331
00332 Loc += (sizeof(cdrfTextInfoChar) * NChars);
00333
00334
00335 TextLine *CurrentLine = new TextLine(TSNode, LASTCHILD);
00336 if(CurrentLine == 0)
00337 goto NoMemory;
00338
00339
00340 INT32 CurrentChar;
00341 for(CurrentChar = 0; CurrentChar < NChars; CurrentChar++)
00342 {
00343 BOOL NewLine = FALSE;
00344
00345 if(IsTextStory == FALSE && CDRDATA_WORD(Chars[CurrentChar].Code) == cdrfTEXT_NEWLINE)
00346 {
00347
00348 Lines++;
00349
00350 if(LineX > MaximumLineX)
00351 MaximumLineX = LineX;
00352
00353
00354 NewLine = TRUE;
00355 }
00356
00357
00358 INT32 Style = ((CDRDATA_WORD(Chars[CurrentChar].Info)) & cdrfTEXTINFOCHAR_INFO_DEFNMASK)
00359 >> cdrfTEXTINFOCHAR_INFO_DEFNMASKSBY;
00360
00361
00362 if(CDRDATA_WORD(Chars[CurrentChar].Code) >= ' ')
00363 {
00364 TextChar *C = new TextChar(CurrentLine, LASTCHILD, CDRDATA_WORD(Chars[CurrentChar].Code));
00365
00366 if(C == 0)
00367 goto NoMemory;
00368
00369 if(Style < 0 || Style >= NFontDefns)
00370 Style = 0;
00371
00372
00373 if(!ApplyTextAttr(C, &Styles[Style], 0 ))
00374 goto NoMemory;
00375 }
00376
00377
00378 LineX += CDRDATA_SWORD(Chars[CurrentChar].XSize);
00379
00380
00381 if(Styles[Style].LineSpace > ThisLineSpace)
00382 ThisLineSpace = Styles[Style].LineSpace;
00383
00384
00385 if(InitialFirstLineSpace == -1)
00386 InitialFirstLineSpace = Styles[Style].LineSpace;
00387
00388 if(NewLine)
00389 {
00390
00391 if(ThisLineSpace < 512)
00392 ThisLineSpace = PreviousLineSpace;
00393 TxtLineSpaceAttribute Attr((FIXED16)(((double)Styles[0].ParaLineSpacePercent) / 100));
00394
00395
00396 if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00397 return FALSE;
00398
00399
00400 EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
00401 if(EOL == 0)
00402 goto NoMemory;
00403
00404 CurrentLine = new TextLine(TSNode, LASTCHILD);
00405 if(CurrentLine == 0)
00406 goto NoMemory;
00407
00408
00409 if(FirstLineSpace == -1)
00410 FirstLineSpace = ThisLineSpace;
00411
00412
00413 LineX = 0;
00414 PreviousLineSpace = ThisLineSpace;
00415 ThisLineSpace = 0;
00416 }
00417 }
00418
00419
00420 if(FirstLineSpace == -1)
00421 FirstLineSpace = ThisLineSpace;
00422
00423
00424 if(ThisLineSpace < 512)
00425 ThisLineSpace = PreviousLineSpace;
00426 TxtLineSpaceAttribute Attr((FIXED16)(((double)Styles[0].ParaLineSpacePercent) / 100));
00427
00428
00429 if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00430 return FALSE;
00431
00432
00433 EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
00434
00435 if(EOL == 0)
00436 goto NoMemory;
00437
00438
00439 delete [] Styles;
00440
00441 PreviousLineSpace = ThisLineSpace;
00442 }
00443
00444
00445 {
00446 Node *LastLine = TSNode->FindLastChild();
00447
00448 if(LastLine == 0)
00449 goto FormError;
00450
00451 Node *LastLineNode = LastLine->FindLastChild();
00452
00453 ERROR3IF(LastLineNode == 0, "Line node doesn't have any children");
00454 ERROR3IF(!LastLineNode->IsKindOf(CC_RUNTIME_CLASS(EOLNode)), "Last entry of a line is not an EOL node");
00455
00456 CaretNode *C = new CaretNode(LastLineNode, PREV);
00457 if(C == 0)
00458 goto NoMemory;
00459 }
00460
00461
00462 if(LineX > MaximumLineX)
00463 MaximumLineX = LineX;
00464
00465
00466
00467
00468 if(IsTextStory)
00469 {
00470 if(FirstLineSpace == -1)
00471 goto FormError;
00472
00473
00474 INT32 Down = (FirstLineSpace * 10) / 12;
00475
00476
00477 INT32 Right = 0;
00478 if(Just == JCENTRE)
00479 {
00480 Right = (FrameX / 2) * CDRCOORDS_TO_MILLIPOINTS;
00481 }
00482 else if(Just == JRIGHT)
00483 {
00484 Right = FrameX * CDRCOORDS_TO_MILLIPOINTS;
00485 }
00486
00487
00488 TSNode->SetStoryMatrix(Matrix(Trans.x+Right, Trans.y-Down));
00489
00490
00491 TSNode->SetImportFormatWidth(FrameX * CDRCOORDS_TO_MILLIPOINTS);
00492 TRACEUSER( "Ben", _T("Import format width initially %d\n"), TSNode->GetImportFormatWidth());
00493
00494
00495 DocRect BBox = DocRect(Trans.x, Trans.y - (FrameY * CDRCOORDS_TO_MILLIPOINTS),
00496 Trans.x + (FrameX * CDRCOORDS_TO_MILLIPOINTS), Trans.y);
00497
00498 TextBBoxes.Add(TSNode, &BBox, JLEFT);
00499 }
00500 else
00501 {
00502
00503 TSNode->SetStoryMatrix(Matrix(0,0));
00504
00505
00506 DocRect BBox = DocRect(0, 0 - FirstLineSpace * Lines,
00507 (MaximumLineX * CDRCOORDS_TO_MILLIPOINTS), FirstLineSpace);
00508
00509 TextBBoxes.Add(TSNode, &BBox, Just);
00510
00511
00512 CheckTextForLinks(TSNode, Header);
00513 }
00514
00515
00516 ObjFilled = TRUE;
00517 ObjStroked = FALSE;
00518
00519
00520 pMadeNode = TSNode;
00521
00522 return TRUE;
00523
00524 NoMemory:
00525 TSNode->CascadeDelete();
00526 delete TSNode;
00527
00528 return FALSE;
00529
00530 FormError:
00531 FormatError = TRUE;
00532 TSNode->CascadeDelete();
00533 delete TSNode;
00534
00535 return TRUE;
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 BOOL CDRFilter::ConvertText4Art(cdrfOffsetHeader *Header)
00553 {
00554
00555 cdrfTextHeaderV4 *Hdr = (cdrfTextHeaderV4 *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
00556
00557
00558 if(Hdr == 0)
00559 {
00560 FormatError = TRUE;
00561 return TRUE;
00562 }
00563
00564 cdrfTextCharV4 *ThisChar = (cdrfTextCharV4 *)(Hdr + 1);
00565
00566
00567 CDRTextStyle BaseStyle;
00568
00569 WORD *StyleRef = (WORD *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_STYLE);
00570 if(StyleRef == 0)
00571 {
00572 FormatError = TRUE;
00573 return TRUE;
00574 }
00575
00576 if(!GetTextStyleFromCDRStyle(&BaseStyle, CDRDATA_WORD(*StyleRef)))
00577 return FALSE;
00578
00579
00580 TextStory *TSNode = new TextStory;
00581
00582 if(TSNode == 0)
00583 return FALSE;
00584
00585
00586 INT32 NChars = CDRDATA_WORD(Hdr->NCharacters);
00587 INT32 CurrentChar;
00588 INT32 MaximumLineSpace = BaseStyle.LineSpace;
00589 INT32 Lines = 1;
00590 INT32 Depth = 0;
00591
00592
00593 TextLine *CurrentLine = new TextLine(TSNode, LASTCHILD);
00594 if(CurrentLine == 0)
00595 goto NoMemory;
00596
00597 for(CurrentChar = 0; CurrentChar < NChars; CurrentChar++)
00598 {
00599 BOOL HasStyles = FALSE;
00600
00601 if(ThisChar->Info != 0)
00602 HasStyles = TRUE;
00603
00604 if(ThisChar->Code >= ' ')
00605 {
00606 TextChar *C = new TextChar(CurrentLine, LASTCHILD, ThisChar->Code);
00607
00608 if(C == 0)
00609 goto NoMemory;
00610
00611
00612 if(HasStyles)
00613 {
00614
00615 cdrfTextCharStyledV4 *SC = (cdrfTextCharStyledV4 *)ThisChar;
00616
00617 CDRTextStyle ThisStyle;
00618
00619 if(!GetTextStyleFromChar4(&ThisStyle, SC, &BaseStyle))
00620 return FALSE;
00621
00622 if(!ApplyTextAttr(C, &ThisStyle, 0))
00623 goto NoMemory;
00624
00625 if(ThisStyle.LineSpace > MaximumLineSpace)
00626 MaximumLineSpace = ThisStyle.LineSpace;
00627 }
00628 else
00629 {
00630
00631 if(!ApplyTextAttr(C, &BaseStyle, 0))
00632 goto NoMemory;
00633 }
00634 }
00635
00636 if(ThisChar->Code == cdrfTEXT_NEWLINE)
00637 {
00638
00639
00640
00641 TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent) / 100));
00642
00643
00644 if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00645 return FALSE;
00646
00647
00648 EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
00649 if(EOL == 0)
00650 goto NoMemory;
00651
00652
00653 CurrentLine = new TextLine(TSNode, LASTCHILD);
00654 if(CurrentLine == 0)
00655 goto NoMemory;
00656
00657
00658 Lines++;
00659 Depth += MaximumLineSpace;
00660 MaximumLineSpace = BaseStyle.LineSpace;
00661 }
00662
00663 if(HasStyles)
00664 {
00665
00666 ThisChar = (cdrfTextCharV4 *)(((cdrfTextCharStyledV4 *)ThisChar) + 1);
00667 }
00668 else
00669 {
00670
00671 ThisChar++;
00672 }
00673 }
00674
00675
00676 {
00677
00678 TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent) / 100));
00679
00680
00681 if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00682 return FALSE;
00683 }
00684
00685 Depth += MaximumLineSpace;
00686
00687
00688 {
00689 EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
00690
00691 if(EOL == 0)
00692 goto NoMemory;
00693
00694
00695 Node *LastLine = TSNode->FindLastChild();
00696
00697 if(LastLine == 0)
00698 goto FormError;
00699
00700 Node *LastLineNode = LastLine->FindLastChild();
00701
00702 ERROR3IF(LastLineNode == 0, "Line node doesn't have any children");
00703 ERROR3IF(!LastLineNode->IsKindOf(CC_RUNTIME_CLASS(EOLNode)), "Last entry of a line is not an EOL node");
00704
00705 CaretNode *C = new CaretNode(LastLineNode, PREV);
00706 if(C == 0)
00707 goto NoMemory;
00708 }
00709
00710
00711 {
00712 TSNode->SetStoryMatrix(Matrix(0,0));
00713
00714
00715 INT32 Width = (MaximumLineSpace * NChars) / (Lines * 3);
00716
00717 DocRect BBox = DocRect(0, 0 - Depth, Width, MaximumLineSpace);
00718
00719 TextBBoxes.Add(TSNode, &BBox, BaseStyle.Just);
00720 }
00721
00722
00723 CheckTextForLinks(TSNode, Header);
00724
00725
00726 ObjFilled = TRUE;
00727 ObjStroked = FALSE;
00728 IsTextStory = FALSE;
00729
00730
00731 pMadeNode = TSNode;
00732
00733 return TRUE;
00734
00735 NoMemory:
00736 TSNode->CascadeDelete();
00737 delete TSNode;
00738
00739 return FALSE;
00740
00741 FormError:
00742 FormatError = TRUE;
00743 TSNode->CascadeDelete();
00744 delete TSNode;
00745
00746 return TRUE;
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 BOOL CDRFilter::ConvertText4Para(cdrfOffsetHeader *Header)
00764 {
00765
00766 cdrfParaTextHeaderV4 *Hdr = (cdrfParaTextHeaderV4 *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
00767
00768
00769 IsTextStory = TRUE;
00770
00771
00772 if(Hdr == 0)
00773 {
00774 FormatError = TRUE;
00775 return TRUE;
00776 }
00777
00778
00779
00780 if(LinkTable == 0)
00781 {
00782
00783 FormatError = TRUE;
00784 return TRUE;
00785 }
00786
00787 cdrfLinkTableHdr *th = (cdrfLinkTableHdr *)LinkTable;
00788
00789 INT32 Entries = CDRDATA_WORD(th->Entries);
00790 BOOL Found = FALSE;
00791 WORD *Offsets = (WORD *)(LinkTable + CDRDATA_WORD(th->OffsetsOffset));
00792 cdrfLinkTableEntryTextV4 *En;
00793 for(INT32 l = 0; l < Entries; l++)
00794 {
00795 En = (cdrfLinkTableEntryTextV4 *)(LinkTable + CDRDATA_WORD(Offsets[l]));
00796
00797 if(CDRDATA_WORD(En->Type) == cdrfLINKTABLEENTRYV4_TEXT &&
00798 CDRDATA_WORD(En->ObjectSerial) == SerialNumber)
00799 {
00800 Found = TRUE;
00801 break;
00802 }
00803 }
00804
00805 if(Found == FALSE)
00806 {
00807 FormatError = TRUE;
00808 return TRUE;
00809 }
00810
00811
00812 CDRVectorStoredItem *Item = (CDRVectorStoredItem *)TextV4.GetHead();
00813
00814
00815 while(Item != 0)
00816 {
00817 if(Item->Reference == CDRDATA_WORD(En->TextID))
00818 {
00819
00820 break;
00821 }
00822
00823 Item = (CDRVectorStoredItem *)TextV4.GetNext(Item);
00824 }
00825
00826 if(Item == 0)
00827 {
00828 FormatError = TRUE;
00829 return TRUE;
00830 }
00831
00832 Node *Text = Item->Objects;
00833
00834
00835 CDRTextStyle BaseStyle;
00836
00837 WORD *StyleRef = (WORD *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_STYLE);
00838 if(StyleRef == 0)
00839 {
00840 FormatError = TRUE;
00841 return TRUE;
00842 }
00843
00844 if(!GetTextStyleFromCDRStyle(&BaseStyle, CDRDATA_WORD(*StyleRef)))
00845 return FALSE;
00846
00847
00848 ERROR2IF(!IS_A(Text, TextLine), FALSE, "Node in text list is not a text line");
00849
00850
00851 TextLine *CurrentLine = (TextLine *)Text;
00852 while(CurrentLine != 0)
00853 {
00854 if(IS_A(CurrentLine, TextLine))
00855 {
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent) / 100));
00871
00872 if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00873 return FALSE;
00874 }
00875
00876 CurrentLine = (TextLine *)CurrentLine->FindNext();
00877 }
00878
00879
00880 TextStory *TSNode = new TextStory;
00881 if(TSNode == 0)
00882 return FALSE;
00883
00884 Text->InsertChainSimple(TSNode, FIRSTCHILD);
00885
00886
00887 Item->Objects = 0;
00888
00889
00890 {
00891 INT32 FirstLineSpace = Item->BBox.hi.y;
00892
00893
00894 INT32 FrameX = CDRDATA_WORD(Hdr->FrameX) * CDRCOORDS_TO_MILLIPOINTS;
00895 INT32 FrameY = CDRDATA_WORD(Hdr->FrameY) * CDRCOORDS_TO_MILLIPOINTS;
00896
00897
00898 INT32 Down = (FirstLineSpace * 10) / 12;
00899
00900
00901 INT32 Right = 0;
00902 if(BaseStyle.Just == JCENTRE)
00903 {
00904 Right = FrameX / 2;
00905 }
00906 else if(BaseStyle.Just == JRIGHT)
00907 {
00908 Right = FrameX;
00909 }
00910
00911
00912
00913 TSNode->SetStoryMatrix(Matrix(Right,-Down));
00914
00915
00916 DocRect BBox = DocRect(0, 0 - FrameY, FrameX, 0);
00917
00918 TextBBoxes.Add(TSNode, &BBox, JLEFT);
00919
00920
00921 TSNode->SetImportFormatWidth(FrameX);
00922 }
00923
00924
00925 delete TextV4.RemoveItem(Item);
00926
00927
00928 pMadeNode = TSNode;
00929 ObjFilled = TRUE;
00930 ObjStroked = FALSE;
00931
00932 return TRUE;
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 BOOL CDRFilter::GetTextStyleFromChar4(CDRTextStyle *TS, cdrfTextCharStyledV4 *Char, CDRTextStyle *BasedOn)
00950 {
00951 if(BasedOn != 0)
00952 *TS = *BasedOn;
00953 else
00954 *TS = CDRDefaultTextStyle;
00955
00956
00957 if((CDRDATA_WORD(Char->Changes) & cdrfSTYLECHANGEV4_FONTNAME) != 0)
00958 {
00959
00960
00961
00962
00963
00964
00965 TS->FontReference = CDRDATA_DWORD(Char->FontRef);
00966 }
00967
00968
00969 if((CDRDATA_WORD(Char->Changes) & cdrfSTYLECHANGEV4_FONTSIZE) != 0)
00970 {
00971 if(CDRDATA_WORD(Char->FontSize) != 0)
00972 {
00973 TS->FontSize = CDRDATA_WORD(Char->FontSize) * CDRCOORDS_TO_MILLIPOINTS;
00974 }
00975 }
00976
00977
00978 TS->LineSpace = (TS->FontSize * (12 * TS->ParaLineSpacePercent)) / 1000;
00979
00980
00981 if((CDRDATA_WORD(Char->Changes) & cdrfSTYLECHANGEV4_WEIGHT) != 0)
00982 {
00983 switch(CDRDATA_WORD(Char->FontType))
00984 {
00985 case cdrfFONTTYPEV4_BOLD:
00986 TS->Bold = TRUE;
00987 TS->Italic = FALSE;
00988 break;
00989
00990 case cdrfFONTTYPEV4_ITALIC:
00991 TS->Bold = FALSE;
00992 TS->Italic = TRUE;
00993 break;
00994
00995 case cdrfFONTTYPEV4_BOLDITALIC:
00996 TS->Bold = TRUE;
00997 TS->Italic = TRUE;
00998 break;
00999
01000 default:
01001 TS->Bold = FALSE;
01002 TS->Italic = FALSE;
01003 break;
01004 }
01005 }
01006
01007 return TRUE;
01008 }
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025 BOOL CDRFilter::ConvertText3(cdrfOffsetHeader *Header)
01026 {
01027
01028 if(Header->ObjectType == (cdrfOBJTYPE_TEXTSTORY - cdrfOBJTYPE_V3ADD))
01029 IsTextStory = TRUE;
01030
01031
01032 cdrfTextHeaderV3 *Hdr = (cdrfTextHeaderV3 *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
01033
01034
01035 if(Hdr == 0)
01036 {
01037 FormatError = TRUE;
01038 return TRUE;
01039 }
01040
01041
01042 INT32 FrameX = CDRDATA_WORD(Hdr->FrameX) * CDRCOORDS_TO_MILLIPOINTS;
01043 INT32 FrameY = CDRDATA_WORD(Hdr->FrameY) * CDRCOORDS_TO_MILLIPOINTS;
01044
01045
01046 cdrfTextCharV3 *ThisChar = (cdrfTextCharV3 *)(Hdr + 1);
01047
01048
01049 CDRTextStyle BaseStyle;
01050
01051 if(!GetTextStyle3(&BaseStyle, CDRDATA_WORD(Hdr->BaseFontStyle)))
01052 return FALSE;
01053
01054
01055 TRACEUSER( "Ben", _T("Justificatoin V3 = %d\n"), Hdr->Justification);
01056 switch(Hdr->Justification)
01057 {
01058 case cdrfJUSTIFICATIONV3_LEFT:
01059 default:
01060 BaseStyle.Just = JLEFT;
01061 break;
01062
01063 case cdrfJUSTIFICATIONV3_CENTRE:
01064 BaseStyle.Just = JCENTRE;
01065 break;
01066
01067 case cdrfJUSTIFICATIONV3_RIGHT:
01068 BaseStyle.Just = JRIGHT;
01069 break;
01070 }
01071
01072
01073 TextStory *TSNode = new TextStory;
01074
01075 if(TSNode == 0)
01076 return FALSE;
01077
01078
01079 INT32 NChars = CDRDATA_WORD(Hdr->NCharacters);
01080 INT32 CurrentChar;
01081 INT32 MaximumLineSpace = BaseStyle.LineSpace;
01082 INT32 Lines = 1;
01083 INT32 Depth = 0;
01084
01085
01086 TextLine *CurrentLine = new TextLine(TSNode, LASTCHILD);
01087 if(CurrentLine == 0)
01088 goto NoMemory;
01089
01090 for(CurrentChar = 0; CurrentChar < NChars; CurrentChar++)
01091 {
01092 BOOL HasStyles = FALSE;
01093
01094 if(ThisChar->Info != 0)
01095 HasStyles = TRUE;
01096
01097 if(ThisChar->Code >= ' ')
01098 {
01099 TextChar *C = new TextChar(CurrentLine, LASTCHILD, ThisChar->Code);
01100
01101 if(C == 0)
01102 goto NoMemory;
01103
01104
01105 if(HasStyles)
01106 {
01107
01108 cdrfTextCharStyledV3 *SC = (cdrfTextCharStyledV3 *)ThisChar;
01109
01110 CDRTextStyle ThisStyle;
01111
01112 if(!GetTextStyle3(&ThisStyle, CDRDATA_WORD(SC->Style), &BaseStyle))
01113 return FALSE;
01114
01115 if(!ApplyTextAttr(C, &ThisStyle, 0))
01116 goto NoMemory;
01117
01118 if(ThisStyle.LineSpace > MaximumLineSpace)
01119 MaximumLineSpace = ThisStyle.LineSpace;
01120 }
01121 else
01122 {
01123
01124 if(!ApplyTextAttr(C, &BaseStyle, 0))
01125 goto NoMemory;
01126 }
01127 }
01128
01129 if(ThisChar->Code == cdrfTEXT_NEWLINE)
01130 {
01131
01132
01133
01134 TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent) / 100));
01135
01136
01137 if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
01138 return FALSE;
01139
01140
01141 EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
01142 if(EOL == 0)
01143 goto NoMemory;
01144
01145
01146 CurrentLine = new TextLine(TSNode, LASTCHILD);
01147 if(CurrentLine == 0)
01148 goto NoMemory;
01149
01150
01151 Lines++;
01152 Depth += MaximumLineSpace;
01153 MaximumLineSpace = BaseStyle.LineSpace;
01154 }
01155
01156 if(HasStyles)
01157 {
01158
01159
01160 ThisChar = (cdrfTextCharV3 *)(((cdrfTextCharStyledV3 *)ThisChar) + 1);
01161 }
01162 else
01163 {
01164
01165
01166 ThisChar++;
01167 }
01168 }
01169
01170
01171 {
01172
01173 TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent) / 100));
01174
01175
01176 if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
01177 return FALSE;
01178 }
01179
01180 Depth += MaximumLineSpace;
01181
01182
01183 {
01184 EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
01185
01186 if(EOL == 0)
01187 goto NoMemory;
01188
01189
01190 Node *LastLine = TSNode->FindLastChild();
01191
01192 if(LastLine == 0)
01193 goto FormError;
01194
01195 Node *LastLineNode = LastLine->FindLastChild();
01196
01197 ERROR3IF(LastLineNode == 0, "Line node doesn't have any children");
01198 ERROR3IF(!LastLineNode->IsKindOf(CC_RUNTIME_CLASS(EOLNode)), "Last entry of a line is not an EOL node");
01199
01200 CaretNode *C = new CaretNode(LastLineNode, PREV);
01201 if(C == 0)
01202 goto NoMemory;
01203 }
01204
01205 if(IsTextStory)
01206 {
01207
01208 INT32 FirstLineHeight = (BaseStyle.LineSpace * 10) / 12;
01209
01210
01211 INT32 Right = 0;
01212 if(BaseStyle.Just == JCENTRE)
01213 {
01214 Right = FrameX / 2;
01215 }
01216 else if(BaseStyle.Just == JRIGHT)
01217 {
01218 Right = FrameX;
01219 }
01220
01221
01222 TSNode->SetStoryMatrix(Matrix(Right, -FirstLineHeight));
01223
01224
01225 DocRect BBox = DocRect(0, 0 - FrameY, FrameX, 0);
01226
01227 TextBBoxes.Add(TSNode, &BBox, JLEFT);
01228
01229
01230 TSNode->SetImportFormatWidth(FrameX);
01231 }
01232 else
01233 {
01234
01235 TSNode->SetStoryMatrix(Matrix(0,0));
01236
01237
01238 INT32 Width = (MaximumLineSpace * NChars) / (Lines * 3);
01239
01240 DocRect BBox = DocRect(0, 0 - Depth, Width, MaximumLineSpace);
01241
01242 TextBBoxes.Add(TSNode, &BBox, BaseStyle.Just);
01243
01244
01245 CheckTextForLinks(TSNode, Header);
01246 }
01247
01248
01249 ObjFilled = TRUE;
01250 ObjStroked = FALSE;
01251
01252
01253 pMadeNode = TSNode;
01254
01255 return TRUE;
01256
01257 NoMemory:
01258 TSNode->Cas