I need to draw a text line where some specified characters would be replaced by arbitrary polygons. These polygons must be painted with Graphics directly using drawPolygon. method. While Unicode contains a range of graphical symbols, they are not appropriate for this task.
I was wondering if it was possible to replace a character with a polygon, in any instance of that character's occurrence in a string?
For example, if I typed-in the word 'Holly' and hit 'enter', the first letter would be replaced by the polygon.
If I then went to type the word 'thistle', the polygon's new position would be in place of the second letter?
Any help/guidance will be greatly appreciated.
Assuming the actual polygon is represented in Unicode all you have to do is string replacement.
System.out.println("Hello".replace('H', '\u25C6'));
produces
◆ello
If you want to display a polygon, may be the easy way is to choose a Unicode symbol
There are lots of them with graphic contents (even a snow man)
This is fully doable with FontMetrics that allow to measure the dimensions of the string as printed with the given font. Use FontMetrics to determine to compute the locations of the string fragments and then draw the string fragments and polygons in between.
This approach seems reasonable if the polygons must be somehow very special (maybe non-Unicode characters?), or they required dimensions are very different from the letter dimensions in the used font.
In early days of Java when the Unicode support was yet not very good, it was not uncommon to draw unsupported national characters that way.
Related
From what I understand, it's up to fonts to turn Arabic (and Persian) characters from their canonical forms (Unicode around 600) to their glyph forms (Unicode around FB00) where appropriate.
(Arabic letters can be connected to their last and/or next character so they usually have 4 different glyph forms)
I am now trying to draw charts using Vaadin with labels which may contain such letters and some specific letters (like 'ک' or 'ی') stay in their base form no matter where they appear in the word, like what I expect is "الکتاب" and what I get is "الکتاب".
The solution I thought of was to manually change every letter into its appropriate glyph form using a HashMap of base forms to an array of glyph forms, but I believe there should be a way to do this in java's libraries. I have seen this answer which does a similar thing using GlyphVector on a font but it's kind of complicated for my case.
Thanks in advance.
I've built a matrix of LEDs controlled by a Java program on my Raspberry Pi. I want to display characters on this matrix. So what I need to do is convert the characters to a two-dimensional boolean-Array (each LED is represented by one boolean).
The only way to do this I can think of is to design a separate matrix for each existing character, but this is way to much work.
Is there any way to do this differently?
You could rasterize (draw) a given font at a given point size using something like AWT or FreeType and then examine the image to see which pixels/LEDs should be on or off.
This will break down as the font size gets smaller. Below some point, you're probably better off coming up with the matrixes yourself rather than pouring a bunch of effort into something that doesn't work.
OTOH, "render-and-read" would be Much Less Boring... so YMMV.
you could load a monochrome image for a character with a pixel size regarding to your led matrix and check with two for loops, whether a pixel at a certain position is black (true) or white (false).
Modern text editors like Notepad++ can visualize control characters like CR, LF, STX, ETX, EOT. I have started to wonder how text editors visualize these characters so neatly.
Note: I am familiar with how encodings and character sets work. And I'm also familiar with the reason why these characters exist.
Some ideas:
Does it apply a special font for these specific characters ?
i.e. a font which contains a representation of all characters.
Or does it use an advanced text-field control/gui-component that renders (i.e. draws) them on the canvas ?
Or does it just replace the characters ? (e.g. replacing a 0x0D with unicode character 0x240D i.e. ␍)
This seems to be the easiest. But then how does it preserve the fact that copying the text still keeps the original text.
The reason for my question: I would like to create a java application that does the same thing.
The 3rd idea should be true, you can replace the charaters with unicode control pictures using a proper font.
There are some inherent problems with assigning glyphs ('images') to Control Codes; most have to do with the case that they already have a particular use! For example, if you send a Tab code to your display, you'd typically expect the cursor to move by a certain number of positions and not to see a character ○ pop up.
Also, typically, fonts use Unicode as their native encoding. Unicode does not allow a glyph to be assigned to the control codes:
Sixty-five code points (U+0000–U+001F and U+007F–U+009F) are reserved as control codes (https://en.wikipedia.org/wiki/Unicode)
There is an 'alias' sort of set defined: U+2400 to U+241F for 0x00 to 0x1f, U+2420 "␠" for "symbol for space", and U+2421 "␡" for "symbol for Delete" (your #3) but then you need to make sure the user has a font that contains these glyphs.
The most configurable way is to 'manually' draw whatever you like. This means you can use any font you want (without the need for a special font), and character replacement is not necessary (only the drawing code need to filter out 'specials'). A drawback, though, is that you are also in charge of drawing regular text.
If that is overkill or you don't have sufficient control over the text draw area, you can simply use different foreground and background colors for the control characters only. This is a screenshot of a quick-and-dirty hex viewer I wrote a while ago – I only change the colors here, but I could have written out custom text for all as well.
For a good overview of what it takes, see James Brown's Design & Implementation of a Win32 Text Editor; it focuses on using Win32 API calls but there is a lot of background as well. Drawing neat Control Codes is addressed in the section Enhanced Drawing & Painting.
My program parses a line of text. In the following picture, I have drawn the bounding boxes around each char as coming from the Tesseract result iterator:
Apparently Tesseract has some problems segmenting the last character ('5') in the line, detecting 3 bounding boxes.
The last character is in fact a tad larger than the other characters, but why would Tesseract segment that character so differently when the pixel blob is thresholded so clearly?
I have set these Tesseract variables:
tess.setVariable("save_blob_choices", "1");
tess.setPageSegMode(PageSegMode.PSM_SINGLE_LINE);
tess.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, "0123456789"
and textord_min_xheight set to the pixel height of the above image
Any suggestions?
I did not find any solution to this problem. Tesseract is so badly documented.
I ended up finding the contour of every character and then passing each sub-image of a character to Tesseract, with the page segmentation mode PSM_SYMBOL. In the end, this was also twice as fast as the previous method!
Is it possible to find the true bounding box of a string in Java? ie the smallest rectangle which includes the pixels which actually get painted?
I have looked at FontMetrics and LineMetrics, and although they allow a string to be passed in, they don't appear to take account of the characters themselves, eh "a", "p" and "P" all return the same height.
Specifically, they seem to include the descent in the string height even if the actual character does not descend below the baseline. Are there other metrics I can access which return a true bounding box?
Alternatively, is there any way to tell if a particular character has a descender?
See this tutorial on measuring text, which is heavily focused on FontMetrics.
The more advanced measurements (to get the bounding box of a particular string), then TextLayout is your friend, as explained here.
In addition to that tutorial on TextLayout, the javadoc contains examples of its use.
You can use javax.swing.SwingUtilities.layoutCompoundLabel. Do not be deterred by the many parameters. There are two versions, the version with the JComponent (may be null) does more flags. It is used for JLabel, so quite versatile, and yields a Rectangle.
BTW That even on "a" a descender might be added to the bounds, is likely to happen here too. You could take the GlyphVector and calculate a bounding box there, but what when font hinting is on, so the pixel positions are slightly off, which error might accumulate over several chars?