Fossil SCM

Update pikchr.c with enhancements in text layout when using "big" or "small".

drh 2020-10-10 20:24 trunk
Commit b80bd64b42fd62175c2d0d9701ae8e288319ab58bcb74e4f4fb70ad56a496087
1 file changed +75 -27
+75 -27
--- src/pikchr.c
+++ src/pikchr.c
@@ -4713,67 +4713,108 @@
47134713
aTxt[i].eCode |= aFree[iSlot++];
47144714
}
47154715
}
47164716
}
47174717
}
4718
+
4719
+/* Return the font scaling factor associated with the input text attribute.
4720
+*/
4721
+static PNum pik_font_scale(PToken *t){
4722
+ PNum scale = 1.0;
4723
+ if( t->eCode & TP_BIG ) scale *= 1.25;
4724
+ if( t->eCode & TP_SMALL ) scale *= 0.8;
4725
+ if( t->eCode & TP_XTRA ) scale *= scale;
4726
+ return scale;
4727
+}
47184728
47194729
/* Append multiple <text> SVG elements for the text fields of the PObj.
47204730
** Parameters:
47214731
**
47224732
** p The Pik object into which we are rendering
47234733
**
4724
-** pObj Object containing the text to be rendered
4734
+** pObj Object containing the text to be rendered
47254735
**
47264736
** pBox If not NULL, do no rendering at all. Instead
47274737
** expand the box object so that it will include all
47284738
** of the text.
47294739
*/
47304740
static void pik_append_txt(Pik *p, PObj *pObj, PBox *pBox){
4731
- PNum dy; /* Half the height of a single line of text */
4732
- PNum dy2; /* Extra vertical space around the center */
47334741
PNum jw; /* Justification margin relative to center */
4742
+ PNum ha2 = 0.0; /* Height of the top row of text */
4743
+ PNum ha1 = 0.0; /* Height of the second "above" row */
4744
+ PNum hc = 0.0; /* Height of the center row */
4745
+ PNum hb1 = 0.0; /* Height of the first "below" row of text */
4746
+ PNum hb2 = 0.0; /* Height of the second "below" row */
47344747
int n, i, nz;
4735
- PNum x, y, orig_y;
4748
+ PNum x, y, orig_y, s;
47364749
const char *z;
47374750
PToken *aTxt;
4738
- int hasCenter = 0;
4751
+ unsigned allMask = 0;
47394752
47404753
if( p->nErr ) return;
47414754
if( pObj->nTxt==0 ) return;
47424755
aTxt = pObj->aTxt;
4743
- dy = 0.5*p->charHeight;
47444756
n = pObj->nTxt;
47454757
pik_txt_vertical_layout(pObj);
47464758
x = pObj->ptAt.x;
4747
- for(i=0; i<n; i++){
4748
- if( (pObj->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
4749
- }
4750
- if( hasCenter ){
4751
- dy2 = dy;
4752
- }else if( pObj->type->isLine ){
4753
- dy2 = pObj->sw;
4754
- }else{
4755
- dy2 = 0.0;
4759
+ for(i=0; i<n; i++) allMask |= pObj->aTxt[i].eCode;
4760
+ if( pObj->type->isLine ) hc = pObj->sw*1.5;
4761
+ if( allMask & TP_CENTER ){
4762
+ for(i=0; i<n; i++){
4763
+ if( pObj->aTxt[i].eCode & TP_CENTER ){
4764
+ s = pik_font_scale(pObj->aTxt+i);
4765
+ if( hc<s*p->charHeight ) hc = s*p->charHeight;
4766
+ }
4767
+ }
4768
+ }
4769
+ if( allMask & TP_ABOVE ){
4770
+ for(i=0; i<n; i++){
4771
+ if( pObj->aTxt[i].eCode & TP_ABOVE ){
4772
+ s = pik_font_scale(pObj->aTxt+i)*p->charHeight;
4773
+ if( ha1<s ) ha1 = s;
4774
+ }
4775
+ }
4776
+ if( allMask & TP_ABOVE2 ){
4777
+ for(i=0; i<n; i++){
4778
+ if( pObj->aTxt[i].eCode & TP_ABOVE2 ){
4779
+ s = pik_font_scale(pObj->aTxt+i)*p->charHeight;
4780
+ if( ha2<s ) ha2 = s;
4781
+ }
4782
+ }
4783
+ }
4784
+ }
4785
+ if( allMask & TP_BELOW ){
4786
+ for(i=0; i<n; i++){
4787
+ if( pObj->aTxt[i].eCode & TP_BELOW ){
4788
+ s = pik_font_scale(pObj->aTxt+i)*p->charHeight;
4789
+ if( hb1<s ) hb1 = s;
4790
+ }
4791
+ }
4792
+ if( allMask & TP_BELOW2 ){
4793
+ for(i=0; i<n; i++){
4794
+ if( pObj->aTxt[i].eCode & TP_BELOW2 ){
4795
+ s = pik_font_scale(pObj->aTxt+i)*p->charHeight;
4796
+ if( hb2<s ) hb2 = s;
4797
+ }
4798
+ }
4799
+ }
47564800
}
47574801
if( pObj->type->eJust==1 ){
47584802
jw = 0.5*(pObj->w - 0.5*(p->charWidth + pObj->sw));
47594803
}else{
47604804
jw = 0.0;
47614805
}
47624806
for(i=0; i<n; i++){
47634807
PToken *t = &aTxt[i];
4764
- PNum xtraFontScale = 1.0;
4808
+ PNum xtraFontScale = pik_font_scale(t);
47654809
orig_y = pObj->ptAt.y;
47664810
PNum nx = 0;
47674811
y = 0;
4768
- if( t->eCode & TP_ABOVE2 ) y += dy2 + 3*dy;
4769
- if( t->eCode & TP_ABOVE ) y += dy2 + dy;
4770
- if( t->eCode & TP_BELOW ) y -= dy2 + dy;
4771
- if( t->eCode & TP_BELOW2 ) y -= dy2 + 3*dy;
4772
- if( t->eCode & TP_BIG ) xtraFontScale *= 1.25;
4773
- if( t->eCode & TP_SMALL ) xtraFontScale *= 0.8;
4774
- if( t->eCode & TP_XTRA ) xtraFontScale *= xtraFontScale;
4812
+ if( t->eCode & TP_ABOVE2 ) y += 0.5*hc + ha1 + 0.5*ha2;
4813
+ if( t->eCode & TP_ABOVE ) y += 0.5*hc + 0.5*ha1;
4814
+ if( t->eCode & TP_BELOW ) y -= 0.5*hc + 0.5*hb1;
4815
+ if( t->eCode & TP_BELOW2 ) y -= 0.5*hc + hb1 + 0.5*hb2;
47754816
if( t->eCode & TP_LJUST ) nx -= jw;
47764817
if( t->eCode & TP_RJUST ) nx += jw;
47774818
47784819
if( pBox!=0 ){
47794820
/* If pBox is not NULL, do not draw any <text>. Instead, just expand
@@ -5998,11 +6039,18 @@
59986039
if( pObj->type->xFit==0 ) return;
59996040
pik_bbox_init(&bbox);
60006041
pik_compute_layout_settings(p);
60016042
pik_append_txt(p, pObj, &bbox);
60026043
w = (eWhich & 1)!=0 ? (bbox.ne.x - bbox.sw.x) + p->charWidth : 0;
6003
- h = (eWhich & 2)!=0 ? (bbox.ne.y - bbox.sw.y) + 0.5*p->charHeight : 0;
6044
+ if( eWhich & 2 ){
6045
+ PNum h1, h2;
6046
+ h1 = (bbox.ne.y - pObj->ptAt.y);
6047
+ h2 = (pObj->ptAt.y - bbox.sw.y);
6048
+ h = 2.0*( h1<h2 ? h2 : h1 );
6049
+ }else{
6050
+ h = 0;
6051
+ }
60046052
pObj->type->xFit(p, pObj, w, h);
60056053
pObj->mProp |= A_FIT;
60066054
}
60076055
60086056
/* Set a local variable name to "val".
@@ -7633,10 +7681,11 @@
76337681
}
76347682
sz = fread(zIn, 1, sz, in);
76357683
fclose(in);
76367684
zIn[sz] = 0;
76377685
zOut = pikchr(zIn, "pikchr", mFlags, &w, &h);
7686
+ if( w<0 ) exitCode = 1;
76387687
if( zOut==0 ){
76397688
fprintf(stderr, "pikchr() returns NULL. Out of memory?\n");
76407689
if( !bDontStop ) exit(1);
76417690
}else if( bSvgOnly ){
76427691
printf("%s\n", zOut);
@@ -7646,11 +7695,10 @@
76467695
zHtmlHdr = 0;
76477696
}
76487697
printf("<h1>File %s</h1>\n", argv[i]);
76497698
if( w<0 ){
76507699
printf("<p>ERROR</p>\n%s\n", zOut);
7651
- exitCode = 1;
76527700
}else{
76537701
printf("<div id=\"svg-%d\" onclick=\"toggleHidden('svg-%d')\">\n",i,i);
76547702
printf("<div style='border:3px solid lightgray;max-width:%dpx;'>\n",w);
76557703
printf("%s</div>\n", zOut);
76567704
printf("<pre class='hidden'>");
@@ -7662,11 +7710,11 @@
76627710
free(zIn);
76637711
}
76647712
if( !bSvgOnly ){
76657713
printf("</body></html>\n");
76667714
}
7667
- return exitCode;
7715
+ return exitCode ? EXIT_FAILURE : EXIT_SUCCESS;
76687716
}
76697717
#endif /* PIKCHR_SHELL */
76707718
76717719
#ifdef PIKCHR_TCL
76727720
#include <tcl.h>
@@ -7726,6 +7774,6 @@
77267774
77277775
77287776
#endif /* PIKCHR_TCL */
77297777
77307778
7731
-#line 7756 "pikchr.c"
7779
+#line 7804 "pikchr.c"
77327780
--- src/pikchr.c
+++ src/pikchr.c
@@ -4713,67 +4713,108 @@
4713 aTxt[i].eCode |= aFree[iSlot++];
4714 }
4715 }
4716 }
4717 }
 
 
 
 
 
 
 
 
 
 
4718
4719 /* Append multiple <text> SVG elements for the text fields of the PObj.
4720 ** Parameters:
4721 **
4722 ** p The Pik object into which we are rendering
4723 **
4724 ** pObj Object containing the text to be rendered
4725 **
4726 ** pBox If not NULL, do no rendering at all. Instead
4727 ** expand the box object so that it will include all
4728 ** of the text.
4729 */
4730 static void pik_append_txt(Pik *p, PObj *pObj, PBox *pBox){
4731 PNum dy; /* Half the height of a single line of text */
4732 PNum dy2; /* Extra vertical space around the center */
4733 PNum jw; /* Justification margin relative to center */
 
 
 
 
 
4734 int n, i, nz;
4735 PNum x, y, orig_y;
4736 const char *z;
4737 PToken *aTxt;
4738 int hasCenter = 0;
4739
4740 if( p->nErr ) return;
4741 if( pObj->nTxt==0 ) return;
4742 aTxt = pObj->aTxt;
4743 dy = 0.5*p->charHeight;
4744 n = pObj->nTxt;
4745 pik_txt_vertical_layout(pObj);
4746 x = pObj->ptAt.x;
4747 for(i=0; i<n; i++){
4748 if( (pObj->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
4749 }
4750 if( hasCenter ){
4751 dy2 = dy;
4752 }else if( pObj->type->isLine ){
4753 dy2 = pObj->sw;
4754 }else{
4755 dy2 = 0.0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4756 }
4757 if( pObj->type->eJust==1 ){
4758 jw = 0.5*(pObj->w - 0.5*(p->charWidth + pObj->sw));
4759 }else{
4760 jw = 0.0;
4761 }
4762 for(i=0; i<n; i++){
4763 PToken *t = &aTxt[i];
4764 PNum xtraFontScale = 1.0;
4765 orig_y = pObj->ptAt.y;
4766 PNum nx = 0;
4767 y = 0;
4768 if( t->eCode & TP_ABOVE2 ) y += dy2 + 3*dy;
4769 if( t->eCode & TP_ABOVE ) y += dy2 + dy;
4770 if( t->eCode & TP_BELOW ) y -= dy2 + dy;
4771 if( t->eCode & TP_BELOW2 ) y -= dy2 + 3*dy;
4772 if( t->eCode & TP_BIG ) xtraFontScale *= 1.25;
4773 if( t->eCode & TP_SMALL ) xtraFontScale *= 0.8;
4774 if( t->eCode & TP_XTRA ) xtraFontScale *= xtraFontScale;
4775 if( t->eCode & TP_LJUST ) nx -= jw;
4776 if( t->eCode & TP_RJUST ) nx += jw;
4777
4778 if( pBox!=0 ){
4779 /* If pBox is not NULL, do not draw any <text>. Instead, just expand
@@ -5998,11 +6039,18 @@
5998 if( pObj->type->xFit==0 ) return;
5999 pik_bbox_init(&bbox);
6000 pik_compute_layout_settings(p);
6001 pik_append_txt(p, pObj, &bbox);
6002 w = (eWhich & 1)!=0 ? (bbox.ne.x - bbox.sw.x) + p->charWidth : 0;
6003 h = (eWhich & 2)!=0 ? (bbox.ne.y - bbox.sw.y) + 0.5*p->charHeight : 0;
 
 
 
 
 
 
 
6004 pObj->type->xFit(p, pObj, w, h);
6005 pObj->mProp |= A_FIT;
6006 }
6007
6008 /* Set a local variable name to "val".
@@ -7633,10 +7681,11 @@
7633 }
7634 sz = fread(zIn, 1, sz, in);
7635 fclose(in);
7636 zIn[sz] = 0;
7637 zOut = pikchr(zIn, "pikchr", mFlags, &w, &h);
 
7638 if( zOut==0 ){
7639 fprintf(stderr, "pikchr() returns NULL. Out of memory?\n");
7640 if( !bDontStop ) exit(1);
7641 }else if( bSvgOnly ){
7642 printf("%s\n", zOut);
@@ -7646,11 +7695,10 @@
7646 zHtmlHdr = 0;
7647 }
7648 printf("<h1>File %s</h1>\n", argv[i]);
7649 if( w<0 ){
7650 printf("<p>ERROR</p>\n%s\n", zOut);
7651 exitCode = 1;
7652 }else{
7653 printf("<div id=\"svg-%d\" onclick=\"toggleHidden('svg-%d')\">\n",i,i);
7654 printf("<div style='border:3px solid lightgray;max-width:%dpx;'>\n",w);
7655 printf("%s</div>\n", zOut);
7656 printf("<pre class='hidden'>");
@@ -7662,11 +7710,11 @@
7662 free(zIn);
7663 }
7664 if( !bSvgOnly ){
7665 printf("</body></html>\n");
7666 }
7667 return exitCode;
7668 }
7669 #endif /* PIKCHR_SHELL */
7670
7671 #ifdef PIKCHR_TCL
7672 #include <tcl.h>
@@ -7726,6 +7774,6 @@
7726
7727
7728 #endif /* PIKCHR_TCL */
7729
7730
7731 #line 7756 "pikchr.c"
7732
--- src/pikchr.c
+++ src/pikchr.c
@@ -4713,67 +4713,108 @@
4713 aTxt[i].eCode |= aFree[iSlot++];
4714 }
4715 }
4716 }
4717 }
4718
4719 /* Return the font scaling factor associated with the input text attribute.
4720 */
4721 static PNum pik_font_scale(PToken *t){
4722 PNum scale = 1.0;
4723 if( t->eCode & TP_BIG ) scale *= 1.25;
4724 if( t->eCode & TP_SMALL ) scale *= 0.8;
4725 if( t->eCode & TP_XTRA ) scale *= scale;
4726 return scale;
4727 }
4728
4729 /* Append multiple <text> SVG elements for the text fields of the PObj.
4730 ** Parameters:
4731 **
4732 ** p The Pik object into which we are rendering
4733 **
4734 ** pObj Object containing the text to be rendered
4735 **
4736 ** pBox If not NULL, do no rendering at all. Instead
4737 ** expand the box object so that it will include all
4738 ** of the text.
4739 */
4740 static void pik_append_txt(Pik *p, PObj *pObj, PBox *pBox){
 
 
4741 PNum jw; /* Justification margin relative to center */
4742 PNum ha2 = 0.0; /* Height of the top row of text */
4743 PNum ha1 = 0.0; /* Height of the second "above" row */
4744 PNum hc = 0.0; /* Height of the center row */
4745 PNum hb1 = 0.0; /* Height of the first "below" row of text */
4746 PNum hb2 = 0.0; /* Height of the second "below" row */
4747 int n, i, nz;
4748 PNum x, y, orig_y, s;
4749 const char *z;
4750 PToken *aTxt;
4751 unsigned allMask = 0;
4752
4753 if( p->nErr ) return;
4754 if( pObj->nTxt==0 ) return;
4755 aTxt = pObj->aTxt;
 
4756 n = pObj->nTxt;
4757 pik_txt_vertical_layout(pObj);
4758 x = pObj->ptAt.x;
4759 for(i=0; i<n; i++) allMask |= pObj->aTxt[i].eCode;
4760 if( pObj->type->isLine ) hc = pObj->sw*1.5;
4761 if( allMask & TP_CENTER ){
4762 for(i=0; i<n; i++){
4763 if( pObj->aTxt[i].eCode & TP_CENTER ){
4764 s = pik_font_scale(pObj->aTxt+i);
4765 if( hc<s*p->charHeight ) hc = s*p->charHeight;
4766 }
4767 }
4768 }
4769 if( allMask & TP_ABOVE ){
4770 for(i=0; i<n; i++){
4771 if( pObj->aTxt[i].eCode & TP_ABOVE ){
4772 s = pik_font_scale(pObj->aTxt+i)*p->charHeight;
4773 if( ha1<s ) ha1 = s;
4774 }
4775 }
4776 if( allMask & TP_ABOVE2 ){
4777 for(i=0; i<n; i++){
4778 if( pObj->aTxt[i].eCode & TP_ABOVE2 ){
4779 s = pik_font_scale(pObj->aTxt+i)*p->charHeight;
4780 if( ha2<s ) ha2 = s;
4781 }
4782 }
4783 }
4784 }
4785 if( allMask & TP_BELOW ){
4786 for(i=0; i<n; i++){
4787 if( pObj->aTxt[i].eCode & TP_BELOW ){
4788 s = pik_font_scale(pObj->aTxt+i)*p->charHeight;
4789 if( hb1<s ) hb1 = s;
4790 }
4791 }
4792 if( allMask & TP_BELOW2 ){
4793 for(i=0; i<n; i++){
4794 if( pObj->aTxt[i].eCode & TP_BELOW2 ){
4795 s = pik_font_scale(pObj->aTxt+i)*p->charHeight;
4796 if( hb2<s ) hb2 = s;
4797 }
4798 }
4799 }
4800 }
4801 if( pObj->type->eJust==1 ){
4802 jw = 0.5*(pObj->w - 0.5*(p->charWidth + pObj->sw));
4803 }else{
4804 jw = 0.0;
4805 }
4806 for(i=0; i<n; i++){
4807 PToken *t = &aTxt[i];
4808 PNum xtraFontScale = pik_font_scale(t);
4809 orig_y = pObj->ptAt.y;
4810 PNum nx = 0;
4811 y = 0;
4812 if( t->eCode & TP_ABOVE2 ) y += 0.5*hc + ha1 + 0.5*ha2;
4813 if( t->eCode & TP_ABOVE ) y += 0.5*hc + 0.5*ha1;
4814 if( t->eCode & TP_BELOW ) y -= 0.5*hc + 0.5*hb1;
4815 if( t->eCode & TP_BELOW2 ) y -= 0.5*hc + hb1 + 0.5*hb2;
 
 
 
4816 if( t->eCode & TP_LJUST ) nx -= jw;
4817 if( t->eCode & TP_RJUST ) nx += jw;
4818
4819 if( pBox!=0 ){
4820 /* If pBox is not NULL, do not draw any <text>. Instead, just expand
@@ -5998,11 +6039,18 @@
6039 if( pObj->type->xFit==0 ) return;
6040 pik_bbox_init(&bbox);
6041 pik_compute_layout_settings(p);
6042 pik_append_txt(p, pObj, &bbox);
6043 w = (eWhich & 1)!=0 ? (bbox.ne.x - bbox.sw.x) + p->charWidth : 0;
6044 if( eWhich & 2 ){
6045 PNum h1, h2;
6046 h1 = (bbox.ne.y - pObj->ptAt.y);
6047 h2 = (pObj->ptAt.y - bbox.sw.y);
6048 h = 2.0*( h1<h2 ? h2 : h1 );
6049 }else{
6050 h = 0;
6051 }
6052 pObj->type->xFit(p, pObj, w, h);
6053 pObj->mProp |= A_FIT;
6054 }
6055
6056 /* Set a local variable name to "val".
@@ -7633,10 +7681,11 @@
7681 }
7682 sz = fread(zIn, 1, sz, in);
7683 fclose(in);
7684 zIn[sz] = 0;
7685 zOut = pikchr(zIn, "pikchr", mFlags, &w, &h);
7686 if( w<0 ) exitCode = 1;
7687 if( zOut==0 ){
7688 fprintf(stderr, "pikchr() returns NULL. Out of memory?\n");
7689 if( !bDontStop ) exit(1);
7690 }else if( bSvgOnly ){
7691 printf("%s\n", zOut);
@@ -7646,11 +7695,10 @@
7695 zHtmlHdr = 0;
7696 }
7697 printf("<h1>File %s</h1>\n", argv[i]);
7698 if( w<0 ){
7699 printf("<p>ERROR</p>\n%s\n", zOut);
 
7700 }else{
7701 printf("<div id=\"svg-%d\" onclick=\"toggleHidden('svg-%d')\">\n",i,i);
7702 printf("<div style='border:3px solid lightgray;max-width:%dpx;'>\n",w);
7703 printf("%s</div>\n", zOut);
7704 printf("<pre class='hidden'>");
@@ -7662,11 +7710,11 @@
7710 free(zIn);
7711 }
7712 if( !bSvgOnly ){
7713 printf("</body></html>\n");
7714 }
7715 return exitCode ? EXIT_FAILURE : EXIT_SUCCESS;
7716 }
7717 #endif /* PIKCHR_SHELL */
7718
7719 #ifdef PIKCHR_TCL
7720 #include <tcl.h>
@@ -7726,6 +7774,6 @@
7774
7775
7776 #endif /* PIKCHR_TCL */
7777
7778
7779 #line 7804 "pikchr.c"
7780

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button