|
Lines 12-17
Link Here
|
| 12 |
package org.eclipse.birt.report.engine.emitter.wpml; |
12 |
package org.eclipse.birt.report.engine.emitter.wpml; |
| 13 |
|
13 |
|
| 14 |
import java.io.OutputStream; |
14 |
import java.io.OutputStream; |
|
|
15 |
import java.text.Bidi; |
| 15 |
import java.util.List; |
16 |
import java.util.List; |
| 16 |
import java.util.StringTokenizer; |
17 |
import java.util.StringTokenizer; |
| 17 |
import java.util.logging.Level; |
18 |
import java.util.logging.Level; |
|
Lines 22-27
Link Here
|
| 22 |
import org.eclipse.birt.report.engine.emitter.XMLWriter; |
23 |
import org.eclipse.birt.report.engine.emitter.XMLWriter; |
| 23 |
import org.eclipse.birt.report.engine.content.IAutoTextContent; |
24 |
import org.eclipse.birt.report.engine.content.IAutoTextContent; |
| 24 |
import org.eclipse.birt.report.engine.css.engine.value.css.CSSConstants; |
25 |
import org.eclipse.birt.report.engine.css.engine.value.css.CSSConstants; |
|
|
26 |
import org.eclipse.birt.report.engine.css.engine.value.birt.BIRTConstants; |
| 25 |
|
27 |
|
| 26 |
public class WpmlWriter |
28 |
public class WpmlWriter |
| 27 |
{ |
29 |
{ |
|
Lines 49-55
Link Here
|
| 49 |
|
51 |
|
| 50 |
protected static Logger logger = Logger.getLogger( WpmlWriter.class |
52 |
protected static Logger logger = Logger.getLogger( WpmlWriter.class |
| 51 |
.getName( ) ); |
53 |
.getName( ) ); |
| 52 |
|
54 |
|
|
|
55 |
// Holds the global layout orientation. |
| 56 |
private boolean rtl = false; // bidi_hcg |
| 57 |
|
| 58 |
// Holds Bidi text information |
| 59 |
private String[] bidiChunks = new String[0]; // bidi_hcg |
| 60 |
private int[] bidiLevels = new int[0]; // bidi_hcg |
| 61 |
|
| 53 |
public WpmlWriter( OutputStream out ) |
62 |
public WpmlWriter( OutputStream out ) |
| 54 |
{ |
63 |
{ |
| 55 |
this( out, "UTF-8" ); |
64 |
this( out, "UTF-8" ); |
|
Lines 60-67
Link Here
|
| 60 |
writer.open( out, encoding ); |
69 |
writer.open( out, encoding ); |
| 61 |
} |
70 |
} |
| 62 |
|
71 |
|
|
|
72 |
/** |
| 73 |
* |
| 74 |
* @deprecated replaced by {@link #start( boolean )} |
| 75 |
*/ |
| 63 |
public void start( ) |
76 |
public void start( ) |
| 64 |
{ |
77 |
{ |
|
|
78 |
start( false ); |
| 79 |
} |
| 80 |
|
| 81 |
public void start( boolean rtl ) |
| 82 |
{ |
| 83 |
this.rtl = rtl; // bidi_hcg |
| 84 |
|
| 65 |
writer.startWriter( ); |
85 |
writer.startWriter( ); |
| 66 |
writer.literal( "\n" ); |
86 |
writer.literal( "\n" ); |
| 67 |
writer.literal( "<?mso-application progid=\"Word.Document\"?>" ); |
87 |
writer.literal( "<?mso-application progid=\"Word.Document\"?>" ); |
|
Lines 108-113
Link Here
|
| 108 |
writer.attribute( "w:val", 4 ); |
128 |
writer.attribute( "w:val", 4 ); |
| 109 |
writer.closeTag( "w:pStyle" ); |
129 |
writer.closeTag( "w:pStyle" ); |
| 110 |
|
130 |
|
|
|
131 |
writeBidi( rtl ); // bidi_hcg |
| 132 |
|
| 111 |
//writer.openTag( "w:tabs" ); |
133 |
//writer.openTag( "w:tabs" ); |
| 112 |
//writer.openTag( "w:tab" ); |
134 |
//writer.openTag( "w:tab" ); |
| 113 |
//writer.attribute( "w:val", "right" ); |
135 |
//writer.attribute( "w:val", "right" ); |
|
Lines 372-377
Link Here
|
| 372 |
writer.closeTag( "w:tblInd" ); |
394 |
writer.closeTag( "w:tblInd" ); |
| 373 |
writeAttrTag( "w:tblStyle", "TableGrid" ); |
395 |
writeAttrTag( "w:tblStyle", "TableGrid" ); |
| 374 |
writeAttrTag( "w:tblOverlap", "Never" ); |
396 |
writeAttrTag( "w:tblOverlap", "Never" ); |
|
|
397 |
|
| 398 |
// bidi_hcg: Bidi layout orientation |
| 399 |
writeBidiTable( ); |
| 400 |
|
| 375 |
writer.openTag( "w:tblW" ); |
401 |
writer.openTag( "w:tblW" ); |
| 376 |
writer.attribute( "w:w", tablewidth ); |
402 |
writer.attribute( "w:w", tablewidth ); |
| 377 |
writer.attribute( "w:type", "dxa" ); |
403 |
writer.attribute( "w:type", "dxa" ); |
|
Lines 387-393
Link Here
|
| 387 |
|
413 |
|
| 388 |
String color = parseColor( style.getBackgroundColor( ) ); |
414 |
String color = parseColor( style.getBackgroundColor( ) ); |
| 389 |
writeBackgroundColor( color ); |
415 |
writeBackgroundColor( color ); |
| 390 |
writeAlign( style.getTextAlign( ) ); |
416 |
|
|
|
417 |
writeAlign( style.getTextAlign( ), |
| 418 |
style.getDirection( ) ); // bidi_hcg |
| 419 |
|
| 391 |
writer.closeTag( "w:tblPr" ); |
420 |
writer.closeTag( "w:tblPr" ); |
| 392 |
} |
421 |
} |
| 393 |
|
422 |
|
|
Lines 421-434
Link Here
|
| 421 |
|
450 |
|
| 422 |
} |
451 |
} |
| 423 |
|
452 |
|
| 424 |
private void writeAlign( String align ) |
453 |
private void writeAlign( String align, String direction ) |
| 425 |
{ |
454 |
{ |
| 426 |
if ( "justify".equalsIgnoreCase( align ) ) |
455 |
if ( "justify".equalsIgnoreCase( align ) ) |
| 427 |
{ |
456 |
{ |
| 428 |
align = "both"; |
457 |
align = "both"; |
| 429 |
} |
458 |
} |
|
|
459 |
// bidi_hcg start |
| 460 |
// Need to swap 'left' and 'right' when orientation is RTL. |
| 461 |
if ( BIRTConstants.BIRT_RTL_VALUE.equalsIgnoreCase( direction ) ) |
| 462 |
{ |
| 463 |
if ( IStyle.CSS_RIGHT_VALUE.equals( align ) ) |
| 464 |
writeAttrTag( "w:jc", IStyle.CSS_LEFT_VALUE ); |
| 465 |
else if ( IStyle.CSS_LEFT_VALUE.equals( align ) ) |
| 466 |
writeAttrTag( "w:jc", IStyle.CSS_RIGHT_VALUE ); |
| 467 |
else |
| 468 |
writeAttrTag( "w:jc", align ); |
| 469 |
} |
| 470 |
// bidi_hcg end |
| 471 |
else |
| 472 |
writeAttrTag( "w:jc", align ); |
| 473 |
} |
| 474 |
|
| 475 |
/** |
| 476 |
* @param direction |
| 477 |
* |
| 478 |
* @author bidi_hcg |
| 479 |
*/ |
| 480 |
private void writeBidi( boolean rtl ) |
| 481 |
{ |
| 482 |
if ( rtl ) |
| 483 |
{ |
| 484 |
writer.openTag( "w:bidi" ); |
| 485 |
writer.closeTag( "w:bidi" ); |
| 486 |
} |
| 487 |
else |
| 488 |
{ |
| 489 |
writeAttrTag( "w:bidi", "off" ); |
| 490 |
} |
| 491 |
} |
| 430 |
|
492 |
|
| 431 |
writeAttrTag( "w:jc", align ); |
493 |
/** |
|
|
494 |
* @param direction |
| 495 |
* |
| 496 |
* @author bidi_hcg |
| 497 |
*/ |
| 498 |
private void writeBidiTable( ) |
| 499 |
{ |
| 500 |
if ( this.rtl ) |
| 501 |
{ |
| 502 |
writer.openTag( "w:bidiVisual" ); |
| 503 |
writer.closeTag( "w:bidiVisual" ); |
| 504 |
} |
| 432 |
} |
505 |
} |
| 433 |
|
506 |
|
| 434 |
private void writeBorders( IStyle style ) |
507 |
private void writeBorders( IStyle style ) |
|
Lines 743-749
Link Here
|
| 743 |
.getCssText( ), ( style |
816 |
.getCssText( ), ( style |
| 744 |
.getProperty( IStyle.STYLE_MARGIN_BOTTOM ) ) |
817 |
.getProperty( IStyle.STYLE_MARGIN_BOTTOM ) ) |
| 745 |
.getCssText( ) ); |
818 |
.getCssText( ) ); |
| 746 |
writeAlign( style.getTextAlign( ) ); |
819 |
writeAlign( style.getTextAlign( ), |
|
|
820 |
style.getDirection( ) ); // bidi_hcg |
| 747 |
String val = parseColor( style.getBackgroundColor( ) ); |
821 |
String val = parseColor( style.getBackgroundColor( ) ); |
| 748 |
writeBackgroundColor( val ); |
822 |
writeBackgroundColor( val ); |
| 749 |
writer.closeTag( "w:pPr" ); |
823 |
writer.closeTag( "w:pPr" ); |
|
Lines 765-770
Link Here
|
| 765 |
openHyperlink( info ); |
839 |
openHyperlink( info ); |
| 766 |
boolean reserved = isReserved( type ); |
840 |
boolean reserved = isReserved( type ); |
| 767 |
|
841 |
|
|
|
842 |
// bidi_hcg start |
| 843 |
// We need to determine Bidi runs and write each run separately, |
| 844 |
// with RTL tags to indicate RTL run direction. Otherwise RTL runs |
| 845 |
// won't be recognized by some Word versions. |
| 846 |
// Non Bidi text will result in a single LTR Bidi run and won't be |
| 847 |
// really affected. |
| 848 |
String direction = style.getDirection( ); |
| 849 |
boolean textIsRtl = BIRTConstants.BIRT_RTL_VALUE.equals( direction ); |
| 850 |
int nChunks = reserved ? 1 : 0; |
| 851 |
|
| 852 |
writer.openTag( "w:pPr" ); |
| 853 |
writeBidi( textIsRtl ); |
| 854 |
writer.closeTag( "w:pPr" ); |
| 855 |
// bidi_hcg end |
| 856 |
|
| 768 |
if ( reserved ) |
857 |
if ( reserved ) |
| 769 |
{ |
858 |
{ |
| 770 |
writer.openTag( "w:r" ); |
859 |
writer.openTag( "w:r" ); |
|
Lines 773-804
Link Here
|
| 773 |
writer.closeTag( "w:fldChar" ); |
862 |
writer.closeTag( "w:fldChar" ); |
| 774 |
writer.closeTag( "w:r" ); |
863 |
writer.closeTag( "w:r" ); |
| 775 |
} |
864 |
} |
| 776 |
|
865 |
// bidi_hcg start |
| 777 |
writer.openTag( "w:r" ); |
866 |
else |
| 778 |
writer.openTag( "w:rPr" ); |
|
|
| 779 |
writeRunProperties( style, info != null ); |
| 780 |
|
| 781 |
if ( prop ) |
| 782 |
{ |
867 |
{ |
| 783 |
writeAlign( style.getTextAlign( ) ); |
868 |
buildBidiChunks( txt, textIsRtl ); |
| 784 |
String val = parseColor( style.getBackgroundColor( ) ); |
869 |
nChunks = bidiChunks.length; |
| 785 |
writeBackgroundColor( val ); |
870 |
assert nChunks > 0; |
| 786 |
writeRunBorders( style ); |
|
|
| 787 |
} |
871 |
} |
|
|
872 |
for ( int i = 0; i < nChunks; i++ ) |
| 873 |
{ |
| 874 |
// bidi_hcg end |
| 788 |
|
875 |
|
| 789 |
writer.closeTag( "w:rPr" ); |
876 |
writer.openTag( "w:r" ); |
|
|
877 |
writer.openTag( "w:rPr" ); |
| 878 |
writeRunProperties( style, info != null ); |
| 790 |
|
879 |
|
| 791 |
if ( reserved ) |
880 |
if ( prop ) |
| 792 |
{ |
881 |
{ |
| 793 |
writeAutoText( type ); |
882 |
// XXX bidi_hcg: It would be expected to only write align for |
|
|
883 |
// the first run, however it seems to work as-is. |
| 884 |
writeAlign( style.getTextAlign( ), |
| 885 |
direction ); // bidi_hcg |
| 886 |
String val = parseColor( style.getBackgroundColor( ) ); |
| 887 |
writeBackgroundColor( val ); |
| 888 |
writeRunBorders( style ); |
| 889 |
} |
| 890 |
// bidi_hcg start |
| 891 |
if ( !reserved |
| 892 |
&& bidiLevels[i] == Bidi.DIRECTION_RIGHT_TO_LEFT ) |
| 893 |
{ |
| 894 |
writer.openTag( "w:rtl" ); |
| 895 |
writer.closeTag( "w:rtl" ); |
| 896 |
} |
| 897 |
// bidi_hcg end |
| 794 |
|
898 |
|
| 795 |
} |
899 |
writer.closeTag( "w:rPr" ); |
| 796 |
else |
|
|
| 797 |
{ |
| 798 |
writeString( txt , style); |
| 799 |
} |
| 800 |
|
900 |
|
| 801 |
writer.closeTag( "w:r" ); |
901 |
if ( reserved ) |
|
|
902 |
{ |
| 903 |
writeAutoText( type ); |
| 904 |
} |
| 905 |
else |
| 906 |
{ |
| 907 |
writeString( bidiChunks[i], style ); |
| 908 |
} |
| 909 |
|
| 910 |
writer.closeTag( "w:r" ); |
| 911 |
} |
| 802 |
if ( reserved ) |
912 |
if ( reserved ) |
| 803 |
{ |
913 |
{ |
| 804 |
writer.openTag( "w:r" ); |
914 |
writer.openTag( "w:r" ); |
|
Lines 872-878
Link Here
|
| 872 |
writeSpacing( style.getLineHeight( ) ); |
982 |
writeSpacing( style.getLineHeight( ) ); |
| 873 |
} |
983 |
} |
| 874 |
|
984 |
|
| 875 |
writeAlign( style.getTextAlign( ) ); |
985 |
writeAlign( style.getTextAlign( ), |
|
|
986 |
style.getDirection( ) ); // bidi_hcg |
| 876 |
|
987 |
|
| 877 |
String val = parseColor( style.getBackgroundColor( ) ); |
988 |
String val = parseColor( style.getBackgroundColor( ) ); |
| 878 |
writeBackgroundColor( val ); |
989 |
writeBackgroundColor( val ); |
|
Lines 888-894
Link Here
|
| 888 |
{ |
999 |
{ |
| 889 |
writer.openTag( "w:p" ); |
1000 |
writer.openTag( "w:p" ); |
| 890 |
writer.openTag( "w:pPr" ); |
1001 |
writer.openTag( "w:pPr" ); |
| 891 |
writeAlign( "center"); |
1002 |
writeAlign( "center", |
|
|
1003 |
null ); // bidi_hcg |
| 892 |
writer.closeTag( "w:pPr" ); |
1004 |
writer.closeTag( "w:pPr" ); |
| 893 |
writer.openTag( "w:r"); |
1005 |
writer.openTag( "w:r"); |
| 894 |
writer.openTag("w:rPr"); |
1006 |
writer.openTag("w:rPr"); |
|
Lines 1313-1326
Link Here
|
| 1313 |
|
1425 |
|
| 1314 |
writeCellProp( style ); |
1426 |
writeCellProp( style ); |
| 1315 |
writer.closeTag( "w:tcPr" ); |
1427 |
writer.closeTag( "w:tcPr" ); |
| 1316 |
|
1428 |
|
| 1317 |
if(style.getTextAlign( ).equals( "left" )) |
1429 |
String direction = style.getDirection( ); // bidi_hcg |
|
|
1430 |
if(style.getTextAlign( ).equals( "left" ) ) |
| 1318 |
{ |
1431 |
{ |
|
|
1432 |
// bidi_hcg start |
| 1433 |
if ( BIRTConstants.BIRT_RTL_VALUE.equals( direction ) ) |
| 1434 |
writeAlign( style.getTextAlign( ), direction ); |
| 1435 |
// bidi_hcg end |
| 1319 |
return ; |
1436 |
return ; |
| 1320 |
} |
1437 |
} |
| 1321 |
|
1438 |
|
| 1322 |
writer.openTag( "w:pPr"); |
1439 |
writer.openTag( "w:pPr"); |
| 1323 |
writeAlign( style.getTextAlign( ) ); |
1440 |
writeAlign( style.getTextAlign( ), direction ); |
| 1324 |
writer.closeTag( "w:pPr"); |
1441 |
writer.closeTag( "w:pPr"); |
| 1325 |
|
1442 |
|
| 1326 |
} |
1443 |
} |
|
Lines 1544-1547
Link Here
|
| 1544 |
|
1661 |
|
| 1545 |
writer.closeTag( "w:p" ); |
1662 |
writer.closeTag( "w:p" ); |
| 1546 |
} |
1663 |
} |
|
|
1664 |
|
| 1665 |
/** |
| 1666 |
* @param text |
| 1667 |
* @param rtl |
| 1668 |
* @return |
| 1669 |
* |
| 1670 |
* @author bidi_hcg |
| 1671 |
*/ |
| 1672 |
private void buildBidiChunks( String text, boolean rtl ) |
| 1673 |
{ |
| 1674 |
Bidi bidiObj = new Bidi( text, rtl ? Bidi.DIRECTION_RIGHT_TO_LEFT |
| 1675 |
: Bidi.DIRECTION_LEFT_TO_RIGHT ); |
| 1676 |
|
| 1677 |
int nRuns = bidiObj.getRunCount( ); |
| 1678 |
if ( nRuns != bidiChunks.length ) |
| 1679 |
{ |
| 1680 |
bidiChunks = new String[nRuns]; |
| 1681 |
bidiLevels = new int[nRuns]; |
| 1682 |
} |
| 1683 |
for ( int i = 0; i < nRuns; i++ ) |
| 1684 |
{ |
| 1685 |
bidiChunks[i] = text.substring(bidiObj.getRunStart( i ), |
| 1686 |
bidiObj.getRunLimit( i ) ); |
| 1687 |
bidiLevels[i] = bidiObj.getRunLevel( i ) & 1; |
| 1688 |
} |
| 1689 |
} |
| 1547 |
} |
1690 |
} |