Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'deltaY', superscript, subscript etc. #4177

Merged
merged 2 commits into from
Aug 12, 2017

Conversation

denim2x
Copy link

@denim2x denim2x commented Aug 7, 2017

  • added deltaY to _styleProperties;
  • updated getSvgSpanStyles for deltaY -> baseline-shift;
  • updated _renderChar to honor deltaY by adjusting top;
  • added functionality for 'superscript' and 'subscript';
  • fixed some bugs 🐞

@@ -131,7 +131,7 @@
timeToRender = this._hasStyleChanged(actualStyle, nextStyle);
}
if (timeToRender) {
style = this._getStyleDeclaration(lineIndex, i) || { };
style = this.getStyleDeclaration(lineIndex, i) || { };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we cannot rename this as part of the PR. _getStyleDeclaration will stay named like this for now.

@asturur
Copy link
Member

asturur commented Aug 7, 2017

a couple of suggestions, leave refactors of properties array and renaming out. Is easier to grasp meaningfull changes.
If you have some ideas about them open a PR later.

Let's concentrate on deltaY support in toSVG and rendering as first step.

* @type Number
* @default
*/
deltaY: 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i m uncertain about this. We should not offer a global deltaY property to the developer.

There is a probably a way to manage style without having the parent property set.

Added 'deltaY' to '_styleProperties' and updated 'getSvgSpanStyles' for 'deltaY' -> 'baseline-shift'
@denim2x denim2x force-pushed the baseline-shift branch 2 times, most recently from 94dfe97 to a0a410c Compare August 8, 2017 06:43
@@ -908,7 +913,7 @@
var box = {
width: width,
left: 0,
height: charStyle.fontSize,
height: style.fontSize,
kernedWidth: kernedWidth,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to have the deltay in the graphmebox information, even if for now we are not using it in the grapheme box context.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we can just return deltay: deltay in the box object, is more than fine for now.

*/
getHeightOfLine: function(lineIndex) {
if (this.__lineHeights[lineIndex]) {
return this.__lineHeights[lineIndex];
}

var line = this._textLines[lineIndex],
maxHeight = this.getHeightOfChar(lineIndex, 0);
maxHeight = Number.NEGATIVE_INFINITY,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this way you are loosing the maxHeight of the first line.
Other than that, text can be in an empty state situation, where there is no text. I would not start from negative_infinity with the risk of getting it as result.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the idea was that we need to take dy into account - and the only way was to start with -Infinity

@asturur
Copy link
Member

asturur commented Aug 8, 2017

I'm unsure about the lineHieght changes.
Moving up a char, should not make the line taller.
We should just need to worried about the first and last line to do not go out of the bounding boxes, but setting the proper values of dy to do not make the text look bad is a developer task, not the library to allow everything to look good. is just too hard.

As a first step would be nice just to see the letters moved up and and down in the render, even if they overlap with others, and the same effect respected in toSVG.

That would be enough small to be readable/reviewable and would be enough working to be mergeable.

@asturur
Copy link
Member

asturur commented Aug 8, 2017

image

this is a screen from google docs. They limit the displacement of apix and pedix to little so that they do not cross line and lineHeight stays the same.

Since we are implementing this property as a tool to get apix and pedix, is ok leave lineHeight calculation out.

Since later i want to introduce per char rotation as svg, i think the measurement logic must be revised useing the boxes of each char. Do not worry now.

@asturur
Copy link
Member

asturur commented Aug 8, 2017

image

they actually nearly overlap

@denim2x
Copy link
Author

denim2x commented Aug 8, 2017

then may I calculate deltaY to fit lineHeight?

@asturur
Copy link
Member

asturur commented Aug 8, 2017

you can go by trying, do not need to get it perfect.
Over the UPPERCASE letters there is like 0.15 space of font size or 0.12. It looks like they are using a 0.5 or 0.4 multiplier.

deltaY = Math.max(deltaY, lineHeight * LINE_PADDING);
}
top += deltaY;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this doing? why we cannot have just top += deltay? i do not understand the math purpose.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well the math ensures there's no overlap; there could be some flag (e.g. allowOverlap) for disabling this behavior (defaults to false)

@asturur
Copy link
Member

asturur commented Aug 8, 2017

no let the overlap free.
we need to be free with rendering and svg overlaps too if it needs it.

The method to set sub or super script can take in consideration overlap, but rendering just excutes the values that find in style.

@denim2x denim2x changed the title Add 'deltaY' attribute 'deltaY', superscript, subscript etc. Aug 9, 2017
@denim2x
Copy link
Author

denim2x commented Aug 9, 2017

🔗 plunker

@@ -1092,7 +1106,7 @@
* @param {Number} top Top coordinate
* @param {Number} lineHeight Height of the line
*/
_renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) {
_renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top, lineHeight) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need that lineHeight? looks like we do not need now.

var decl = this._getStyleDeclaration(line, char) || {};
decl[key] = value;
this._setStyleDeclaration(line, char, decl);
return value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think we should return a value with the setter. We can return this and make it chainable

@asturur
Copy link
Member

asturur commented Aug 9, 2017

I think is everything ok. I left a pair of comments and i have some comment to write about the scale function that is too much general for what we have to do. Let me think a bit about it.

@@ -60,7 +60,6 @@

/**
* Returns styles-string for svg-export
* @param {Boolean} skipShadow a boolean to skip shadow filter output
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you mind correcting the JSDOC here?

  • @param {Object} style object to getthe style-string from

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@asturur
Copy link
Member

asturur commented Aug 10, 2017

I would prefere something like this for both sup and sub script

   setSuperscript: function(line, char) {
         var currentFontSize = this.getPropertyAt(line, char, 'fontSize');
         var currentBaseline = this.getPropertyAt(line, char, 'baseline');
         setPropertyAt(line, char, 'fontSize', currentFontSize * this.superscript.fontSize);
         setPropertyAt(line, char, 'deltaY', baseline  - currentFontSize * this.superscript.baseline);
         return this;
   },

Is shorter than the general one and we do not have any general case to apply this for.
Any reason why you think the scale function is necessary?

I m really trying to just save space and code to mantain. Fabric is a big library full of features that maybe should not be introduced at all at the time.

I'm sorry if it looks like i'm spoon feeding you.

@denim2x
Copy link
Author

denim2x commented Aug 10, 2017

fine by me

@asturur
Copy link
Member

asturur commented Aug 10, 2017

image

take care of this ^^^^

if you cloned the repository, you should have a command line
npm run lint that would allow you to check this beforehand.

Also try to add a small test for setSubscript and setSuperScript so that it verifies that after calling the method the style is mutated.

i can provide a snippet for you.

I would merge this then.

After this is merged we would need some more work to displace the cursor that i believe does not follow the superscript. Probably it automatically gets the size but not the baseline.

Do not worry for now do not mix it here.

@asturur
Copy link
Member

asturur commented Aug 10, 2017

test example

  test('text superScript', function() {
    var text = new fabric.Text('xxx', { fontSize: 30 });
    text.styles = { 0: { 0: { fontSize: 20, fill: 'blue' }, 1:  { fill: 'blue' }}};
    ok(typeof text.setSuperScript === 'function');
    equal(text.styles[0][0].baseline, undefined, 'the baseline is not set');
    equal(text.styles[0][1].baseline, undefined, 'the baseline is not set');
    text.setSuperScript(0, 0);
    text.setSuperScript(0, 1);
    equal(text.styles[0][0].fontSize,....., 'the fontSize has been.... add description');
    equal(text.styles[0][0].baseline, ...., 'baseline is now a portion of ...');
// then verify for the char 1 that has no fontSize in the style
    equal(text.styles[0][1].fontSize,....., 'the fontSize has been.... add description');
    equal(text.styles[0][1].baseline, ...., 'baseline is now a portion of ...');
  });

@asturur
Copy link
Member

asturur commented Aug 10, 2017

I was also thinking that while the fontsize is multiplied the baseline is added. This is ok for 1 usage of superscript.

The functionality is generic enough so that i can set superscript twice, but i need to add the baseline to the current one.
Since deltaY is not a property of the text prototype and probably should not be, i think we need a special handling when we get is as undefined to interpret as 0.

@denim2x
Copy link
Author

denim2x commented Aug 10, 2017

when do we need 'deltaY == 0'? I always check for the presence of 'deltaY' in my code - when rendering and converting to SVG

@asturur
Copy link
Member

asturur commented Aug 10, 2017

I made the ipothesis of calling setSuperScript twice.

The font mulitplication works. Because it gets multiplies by some 0.x twice. So the char gets smaller and smaller.

The second time you call it, baseline would be erased and recalculated by the current fontSize that is the one of the first call of setSuperScript, while thinking of making the apix of the apix, you would need to displace the character UP by what it was before plus a portion of the currentFontsize.

This bring in the need of knowing the current baseline. the current baseline may be undefined.

@denim2x
Copy link
Author

denim2x commented Aug 10, 2017

I'll check it

@asturur
Copy link
Member

asturur commented Aug 10, 2017

#4177 (comment)

in this comment i was adding it in that small function example

@denim2x
Copy link
Author

denim2x commented Aug 10, 2017

well what do you know - it works! I just had to do dy + size * ...

@denim2x denim2x force-pushed the baseline-shift branch 5 times, most recently from 60021f3 to 045fe04 Compare August 10, 2017 18:34
 Honors 'deltaY' during rendering; provides functionality for 'superscript' & 'subscript'; some bug-fixing
@asturur
Copy link
Member

asturur commented Aug 12, 2017

i think we are over engineering the solution.
all the schema thing is way overcomplicated for me, the plain function is the best in my opinion.

we need tests to pass. are you able to run tests locally on your end?

@denim2x
Copy link
Author

denim2x commented Aug 12, 2017

first off - when you said scaleChar should go - well, it's gone;
secondly, well - there's absolutely no point in writing the same code twice (DRY anyone?);
and last (but not least), have you checked the plunker I posted?

@asturur
Copy link
Member

asturur commented Aug 12, 2017 via email

@asturur
Copy link
Member

asturur commented Aug 12, 2017 via email

@asturur
Copy link
Member

asturur commented Aug 12, 2017

so the feature is working, tests do not pass but i think i can fix them.
I m going to merge this branch, fix the tests in a PR.

We should try to fix the cursor look that is not in the right position during deltaY displacement.

@asturur asturur merged commit ffc5cd7 into fabricjs:baseline-shift Aug 12, 2017
@denim2x
Copy link
Author

denim2x commented Aug 12, 2017

ok

asturur added a commit that referenced this pull request Mar 1, 2018
* 'deltaY', superscript, subscript etc. (#4177)
thiagocunha pushed a commit to thiagocunha/fabric.js that referenced this pull request Nov 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants