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

ClickableSpan support in widget #2

Closed
AbdullahRusi opened this issue Jan 11, 2018 · 12 comments
Closed

ClickableSpan support in widget #2

AbdullahRusi opened this issue Jan 11, 2018 · 12 comments

Comments

@AbdullahRusi
Copy link

السلام علیکم ورحمة الله وبرکاته

Brother please consider implementing this useful feature, use cases include support of clicking on individual word, having some links with references etc

As of now widget doesn't have ClickableSpan support to use something like this:

static View.OnTouchListener ssilkaToch = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { boolean ret = false; CharSequence text = ((TextView) v).getText(); Spannable stext = Spannable.Factory.getInstance().newSpannable(text); TextView widget = (TextView) v; int action = event.getAction();
		if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
			int x = (int) event.getX();
			int y = (int) event.getY();

			x -= widget.getTotalPaddingLeft();
			y -= widget.getTotalPaddingTop();

			x += widget.getScrollX();
			y += widget.getScrollY();

			Layout layout = widget.getLayout();
			int line = layout.getLineForVertical(y);
			int off = layout.getOffsetForHorizontal(line, x);

			ClickableSpan[] link = stext.getSpans(off, off, ClickableSpan.class);

			if (link.length != 0) {
				if (action == MotionEvent.ACTION_UP) {
					link[0].onClick(widget);
				}
				ret = true;
			}
		}
		return ret;
	}
};

My use case is support of clicking on individual word and get it recitated or meaning searched through dictionary. Also needed setLineSpacing
Thank you for your effort and support

@mta452
Copy link
Member

mta452 commented Jan 21, 2018

وعلیکم السلام ورحمة اللہ وبرکاتہ

I have added experimental support for hit testing. So your above example should work by modifying to something like this:

		if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
			int x = (int) event.getX();
			int y = (int) event.getY();

			x += widget.getScrollX();
			y += widget.getScrollY();

			int off = label.getCharIndexFromPosition(x, y);
			ClickableSpan[] link = stext.getSpans(off, off, ClickableSpan.class);

			if (link.length != 0) {
				if (action == MotionEvent.ACTION_UP) {
					link[0].onClick(widget);
				}
				ret = true;
			}
		}
		return ret;

@AbdullahRusi
Copy link
Author

AbdullahRusi commented Jan 22, 2018

جزاك الله خيراً
New feature is working.
But it seems latest commits introduced some regression and slowdowns when text appears and it's not aligned properly.
Glitches appearing randomly - changing when going off screen and scroll back again.
Update: removed screenshot from app cause it's not needed now.

@mta452
Copy link
Member

mta452 commented Jan 24, 2018

Sorry for the mishaps. As of now, lines are being manually created in label widget. Eventually, they will be replaced by a single ComposedFrame object. But before that, support for ParagraphStyle spans need to be added.

I implemented a quick solution for hit test by calculating line positions beforehand. Apparently, change in gravity did not request re-layout. Maybe that's what caused glitches. I have pushed a fix for this case. Hopefully it will resolve the issue.

For performance, you might want to use typesetters instead of spanned strings. Also, make sure to run the app in release mode.

@AbdullahRusi
Copy link
Author

AbdullahRusi commented Jan 27, 2018

السلام علیکم ورحمة الله وبرکاته
جزاك الله خيراً
Tried this fix and unfortunately nothing changed.
Glitches are still there.
Here is patch for demo app to reproduce this bug
reproduce_glitch.zip
And here is small patch to remove NDK errors about deprecated ABIs, it's already included in the one above.
fix_ndk_errors_and_warnings_on_deprecated_ABIs.zip

@mta452
Copy link
Member

mta452 commented Jan 27, 2018

وعلیکم السلام ورحمة اللہ وبرکاتہ
I have fixed the glitches. Please check the latest commit.
The abi filters were left as a choice. Maybe this error occurs in a new gradle version. I'll definitely look into it.

@AbdullahRusi
Copy link
Author

AbdullahRusi commented Jan 28, 2018

السلام عليكم ورحمة الله وبركاته
جزاك الله خيراً
بارك الله فيكم

Thank you for your effort and fast fix.

Source of tajweed markup i have originally was this: https://github.com/GlobalQuran/data/blob/master/Quran/quran-tajweed.txt

Which was using tanzil.net text - seems like it was variant of Uhthmanic script with rub-el-hizb, but not version with different tanween shapes support.

Then i've got xml markup from it with some simple scripts.

Bi`izniLLahi i've done support for different tanween shapes in almost all fonts i have.

I think it's worth to make inshaa Allah new markup using text with different tanween shapes support from tanzil.net

May be you have some ideas how to improve markup or is it possible to enhance color support in ligatures.

Actually i want for you brother to participate in such task: inshaa Allah prepare/impove data/markup to use with your good library to display as correct as possible Mushaf with tajweed rules. It may become inshaa Allah as useful as tanzil.net prepared text.

If you interested i'm ready to share markup

@mta452
Copy link
Member

mta452 commented Jan 31, 2018

وعلیکم السلام ورحمة اللہ وبرکاتہ

Maybe I'm missing something but I have not been able to color tajweed rules in tanzil.net.

Please note that individual characters cannot be recognized in a ligature. The best a font developer can do is provide advance width for each character in Ligature Caret List Table table. But even this table is optional and might not work correctly if characters are overlapping, such as a lam-alef ligature. Things get more complicated when a component of a ligature has marks on it, such as lam-fatha-alef. In this case, all three characters will form a cluster of two glyphs, lam-alef ligature and fatha mark. So they will no longer be individually recognizable.

Having said all that, there are definitely ways of improvement. Currently, SheenFigure only provides character to glyph mapping based on clusters. I can add the ability for glyph to character mapping as well, based on actual characters. This way, marks would become recognizable in a cluster. For ligatures, Ligature Caret List Table can be utilized if available. Otherwise, individual character width can be approximated simply by dividing ligature width with total number of components. Then in Tehreer-Android, an algorithm would be integrated to make ligature splitable runs and finally the ability to draw parts of ligature by clipping.

The process is complex, but I can add these features one by one. It might take a long time, so don't get your hopes high.

Alternatively, you may update the fonts by converting all ligatures to individual glyphs along with their substitution and positioning rules.

@AbdullahRusi
Copy link
Author

السلام عليكم ورحمة الله وبركاته
الحمد لله
Bi`izniLLahi i succeed in adding support for different tanween shapes to existing markup.
So now i'm looking forward to improvements in shaa Allah.
As you mentioned it's complex process and it might take a long time.
Wish you succeed implementing it in shaa Allah.
Can't help you with coding, maybe info from theese links become useful for you
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html
https://github.com/fonttools/fonttools/search?q=lcar&type=Commits
As of now fonttools seems to me the only possible tool for trying to add this table to fonts

@mta452
Copy link
Member

mta452 commented Feb 8, 2018

وعلیکم السلام ورحمة اللہ وبرکاتہ

You have started a noble project and it would be an honor to work on it. But it would be too difficult for me to maintain these many projects. Maybe you can open source this project and one day I might start contributing in it with pull requests. As of now, my top priority is the addition of missing features in SheenFigure and Tehreer-Android.

Regarding font technologies, AAT seems to be fully supported on apple devices only. So it would be better to use OpenType instead. This link will be of interest to you: https://www.adobe.com/devnet/opentype/afdko/topic_overview.html

@mta452
Copy link
Member

mta452 commented Apr 1, 2018

Hit testing can be performed with int hitTestPosition(float x, float y) in TLabel. For more information like line number or run index, composedFrame can be directly accessed from TLabel. Line spacing can be configured with setExtraLineSpacing(float extraLineSpacing) and setLineHeightMultiplier(float lineHeightMultiplier). Please see the release notes for a complete list of changes in version 2.1.

@mta452 mta452 closed this as completed Apr 1, 2018
@AbdullahRusi
Copy link
Author

السلام علیکم ورحمة الله وبرکاته
جزاك الله خيراً
Nice to see changes landed to stable version.
Brother you mentioned that it's possible to use Typesetter directly for perfomance reasons.
Can you give me an example how to do it properly?
As of now i don't see benefits of using it instead of setSpanned.
If i use code like in updateTypesetter function in TLabel and then invoke setTypesetter.

@mta452
Copy link
Member

mta452 commented Apr 7, 2018

وعلیکم السلام ورحمة اللہ وبرکاتہ

The creation of typesetter is an expensive operation. It runs different operations on text such as Line Breaking, BiDi, Span Handling and OpenType Shaping. So if you can lazy create typesetters and cache them for later use, that would increase the performance. But of course, you need to make sure first if there are performance issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants