Font issue in creating PDF by LibHaru(UTF-8)? - c++

I tried to generate pdf files with libharu. There are many different languages input in my case, so I chose the encoder(UTF-8). The following architecture is about my code:
HPDF_UseUTFEncodings(pdf);
HPDF_SetCurrentEncoder(pdf, "UTF-8");
const char * font_name = HPDF_LoadTTFontFromFile(pdf, "ArialUnicodeMS.ttf", HPDF_TRUE);
HPDF_Font font = HPDF_GetFont(pdf, font_name, "UTF-8");
HPDF_Page_SetFontAndSize(page, font, 12);
HPDF_Page_BeginText(page);
HPDF_Page_MoveTextPos(page, 60 + i * 100, height - 75);
HPDF_Page_ShowText(page, font_name[i]);
HPDF_Page_EndText(page);
Here are my testing input: "тест", "テスト", "Ölçek", "ทดสอบ", "테스트", "測試", "测试". The library worked, but not in every fonts. I know I shoud use the font support UTF-8, so I have tried ArialUnicodeMS, DroidSans, DroidSansFallback, DroidSansFallbackFull. Only ArialUnicodeMS can output all inputs. I use FontForge to check the difference between these fonts, but DroidSans also povides characters I want. Please tell me the reason about this situation, thanks a lot.

Related

Unit test on fixture in SVG generated with Batik

I'm trying to unit test generated svg in batik.
My development machine is windows,
my CI environment is Linux,
I use a a fixture to compare the svg result with my input, thus comparing the generated svg with what I've got in a file in my test/resource folder
I want my environments to be identical, so what I see in my development environment is what I get.
Initially I used the standard monospaced font.
To avoid the problem I tried the following: The documentation on Batik seems to suggest its possible to include the font in the generated svg to make it "self contained". I found out there are 2 options:
include the font definition
render the text themselves as strokes
That does not work either. Rendering takes place on the font definition before inclusion in the svg. I found there's a difference: java uses the system (windows/linux) font rendering to determine the font definition. They work differently. There are some articles on that topic.
But why render if you use monospaced fonts? The result should be the same, right? In the case of svg, I really would like to delegate rendering to the platform (browser or other tool) interpreting the svg.
My code:
DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
// Create an instance of org.w3c.dom.Document.
Document document = domImpl.createDocument( "http://www.w3.org/2000/svg", "svg", null );
// embed fonts in svg document
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault( document );
ctx.setEmbeddedFontsOn( true );
GraphicsEnvironment ge;
try {
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont( Font.createFont( Font.TRUETYPE_FONT, this.getClass().getResourceAsStream( "/font/VeraMono.ttf" ) ) );
}
catch ( FontFormatException | IOException e ) {
LOG.error( "Cannot load font!", e );
}
// Create an instance of the SVG Generator: true converts text to paths.
SVGGraphics2D g2 = new SVGGraphics2D( ctx, true );
g2.setFont( new Font( "VeraMono", Font.PLAIN, 20 ) );
g2.drawString( "example text", 5, 30 );

Use MFC CRichEditCtrl to display QR code with proper size

I am trying to display a QR code in a MFC CRichEditCtrl, but the resulting size is way too small.
This is the code I'm using to put the QR into the edit control:
SETTEXTEX TextInfo = {0};
TextInfo.flags = ST_SELECTION;
TextInfo.codepage = CP_UTF8;
LRESULT res = ::SendMessage(m_editQR.m_hWnd, EM_SETTEXTEX, (WPARAM)&TextInfo, (LPARAM)buffer);
The "buffer" parameter is a char array; its content is read from a UTF-8 file containing the QR code string. This file shows this way in Notepad++:
The QR code also shows correctly if I print the same buffer in a console app I made for tests.
However, the QR code is shown in my MFC testing app like this:
It looks like a problem with the size of the font used to render the QR (I'm using the default for the Rich Edit control). So I tried to change the font and its size.
This is the code I'm using to set up the char format:
CHARFORMAT selCharformat;
m_editQR.GetSelectionCharFormat(selCharformat);
selCharformat.cbSize = sizeof(CHARFORMAT);
selCharformat.dwMask = CFM_FACE | CFM_SIZE | CFM_CHARSET;
selCharformat.yHeight = 20*8;
selCharformat.bCharSet = DEFAULT_CHARSET;
selCharformat.bPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
lstrcpy(selCharformat.szFaceName, _T("Console"));
BOOL bRes = m_editQR.SetSelectionCharFormat(selCharformat);
But then the QR is messed up, like this:
I guess there is a problem with the setup of my Rich Edit ctrl, but can't find the correct settings (I'm not very experienced with MFC).
Can you guys help?

Set line spacing in QTextEdit

I want to set the line spacing of a QTextEdit.
It's no problem to get that information with
QFontMetrics::lineSpacing();
But how to set that?
I tried with StyleSheets, but that didn't work:
this->setStyleSheet("QTextEdit{ height: 200%; }");
or
this->setStyleSheet("QTextEdit{ line-height: 200%; }");
Partial solution:
Well, I've found a solution - not the way I wanted it, but at least it's simple and it gives nearly my intended behavior, enough for my proof of concept.
On every new line there's some linespacing. But if you just type until the text is automatically wrapped to a new line you wont have line-spacing between this two lines. This hack only works with text blocks, see the code.
Just keep in mind it's brute force and a ugly hack. But it provides some kind of line-spacing to your beautiful QTextEdit. Call it everytime your text changes.
void setLineSpacing(int lineSpacing) {
int lineCount = 0;
for (QTextBlock block = this->document()->begin(); block.isValid();
block = block.next(), ++lineCount) {
QTextCursor tc = QTextCursor(block);
QTextBlockFormat fmt = block.blockFormat();
if (fmt.topMargin() != lineSpacing
|| fmt.bottomMargin() != lineSpacing) {
fmt.setTopMargin(lineSpacing);
//fmt.setBottomMargin(lineSpacing);
tc.setBlockFormat(fmt);
}
}
}
The QFontMetrics contains (per the name) static properties that come from the font file. How wide a capital "C" is, etc. lineSpacing() gets you the natural distance in single-spacing that the person who designed the font encoded into the font itself. If you actually wanted to change that (you don't)...the somewhat complicated story of how is told here:
http://fontforge.sourceforge.net/faq.html#linespace
As for the line spacing in a QTextEdit...it looks (to me) like that is seen as one of the things that falls under Qt's extensibility model for specifying text "layouts":
http://doc.qt.io/qt-4.8/richtext-layouts.html
You would supply your own layout class to the QTextDocument instead of using the default. Someone tried it here but did not post their completed code:
http://www.qtcentre.org/threads/4198-QTextEdit-with-custom-space-between-lines
I know this is an old question, but I've spent a lot of time today trying to solve this for PyQt5 5.15.2. I'm posting my solution in case it is useful to others. The solution is for Python, but should be easily transferable.
The following code will change the line height to 150% for a populated QTextEdit widget in one go. Further editing will pick up the current block format, and continue applying it. I've found it to be very slow for large documents though.
textEdit = QTextEdit()
# ... load text into widget here ...
blockFmt = QTextBlockFormat()
blockFmt.setLineHeight(150, QTextBlockFormat.ProportionalHeight)
theCursor = textEdit.textCursor()
theCursor.clearSelection()
theCursor.select(QTextCursor.Document)
theCursor.mergeBlockFormat(blockFmt)
Applying blockformat to entire document rather than each line works.
QTextBlockFormat bf = this->textCursor().blockFormat();
bf.setLineHeight(lineSpacing, QTextBlockFormat::LineDistanceHeight) ;
this->textCursor().setBlockFormat(bf);
I have translated Jadzia626's code to C++ and it works. Here is the information about setLineHeight()
qreal lineSpacing = 35;
QTextCursor textCursor = ui->textBrowser->textCursor();
QTextBlockFormat * newFormat = new QTextBlockFormat();
textCursor.clearSelection();
textCursor.select(QTextCursor::Document);
newFormat->setLineHeight(lineSpacing, QTextBlockFormat::ProportionalHeight);
textCursor.setBlockFormat(*newFormat);

How to display Red Squiggly Lines in CRichEditCtrl in MFC

I am working on implementing spellchecker in an MFC application. What I want to do is display red lines under incorrectly spelled words.
I found one example where it is done but it works only for a simple edit box because it can simply use the edit controls default font for doing calculations to draw the squiggly lines. But it does not work for a rich edit control as in rich edit control it is possible that different words can have different fonts. In this case the example I found draws lines at incorrect places.
Please let me know if someone has already done this for CRichEditCtrl? (it must handle text of any font/size that is present in the rich edit control.)
Thanks,
Sachin
CHARFORMAT2 format;
SecureZeroMemory(&format, sizeof(CHARFORMAT2));
format.cbSize = sizeof(CHARFORMAT2);
format.dwMask = CFM_UNDERLINE|CFM_UNDERLINETYPE;
format.dwEffects = CFE_UNDERLINE;
format.bUnderlineType = CFU_UNDERLINEWAVE | 0x50;
SendMessage(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&format);
I hope this will get the underline in your text
Use the EM_SETCHARFORMAT message:
CHARFORMAT2 format;
SecureZeroMemory(&format, sizeof(CHARFORMAT2));
format.cbSize = sizeof(CHARFORMAT2);
format.dwMask = CFM_UNDERLINE|CFM_UNDERLINETYPE;
format.dwEffects = CFE_UNDERLINE;
format.bUnderlineType = CFU_UNDERLINE
window->SendMessage(EM_EXSETSEL, NULL, (LPARAM)&range);
window->SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);

Export every frame as image from a Movie-File (QuickTime-API)

I want to open an existing Movie-File and export every frame of this file to an image like JPEG or TIFF. I got so far until now:
int main(int argc, char* argv[]) {
char filename[255]; // Filename to ping.
OSErr e; // Error return.
FSSpec filespec; // QT file specification
short filemovie; // QT movie handle.
Movie movie; // QT movie "object".
InitializeQTML(0);
EnterMovies();
// Because of QT's Mac origin, must convert C-string filename
// to Pascal counted string, then use that to make a filespec.
c2pstr(filename);
FSMakeFSSpec(0, 0L, (ConstStr255Param)filename, &filespec);
OpenMovieFile(&filespec, &filemovie, fsRdPerm);
NewMovieFromFile(&movie, filemovie, nil, nil, newMovieActive, nil);
...
Until now it works fine (I tested with TimeValue movietime = GetMovieDuration(movie); and print it), but now I want to get every frame of the movie and export it to a file (for first, later i just want to keep the data in memory to work with it, but i have to know if it really works, so export to an image-file is better for now).
How do I do that? Do I need a GWorld or a PixMap? How do I get a GWorld/PixMap from a Movie-File, especially each frame of it?
edit: My Platform is WinXP
As a beginning, this article on Movie exporters should pretty much get you started:
http://www.mactech.com/articles/mactech/Vol.16/16.05/May00QTToolkit/index.html
Even though MacTech is a Mac resource, all described API functions should be available in the QuickTime for Windows SDK as well.
I will slap some sample code together myself as a reference here as soon as I find the time.
Edit
See this book excerpt for additional info:
QuickTime Toolkit - Basic Movie Playback and Media Types # Google Books
Edit 2 - The High-Level Approach: Movie Exporters
If all you need to accomplish is to extract all video frames from a QuickTime Movie and convert them to another format supported by the QuickTime API you won't have to take any low-level actions whatsoever if using a Movie Exporter.
The below sample code allows to extract and convert all video frames from a QuickTime Movie to, f.e., a bunch of JPEG files using a programmatically invoked Movie Export Dialog.
Just select Movie to Image Sequence in the Export combo box of the dialog and select your desired image format by hitting Options.
Note 1: If you need to do this non-interactively, just let me know.
Note 2: error handling has been omitted for clarity
#include "Movies.h"
#include "QTML.h"
#pragma comment (lib, "QTMLClient.lib")
...
int flags = createMovieFileDeleteCurFile
| showUserSettingsDialog
| movieToFileOnlyExport;
ItemCount movie_prop_count = 0;
CFStringRef cfpath = 0;
Boolean bool_true = true;
QTNewMoviePropertyElement movie_props[ 2 ];
Movie movie;
// initialize QuickTime API
InitializeQTML( 0 );
EnterMovies();
// set up Core Foundation string for source path (argv[ 1 ]) contains the full path to the MOV file to convert
cfpath = CFStringCreateWithCString( 0, argv[ 1 ], kCFStringEncodingASCII );
movie_props[movie_prop_count].propClass = kQTPropertyClass_DataLocation;
movie_props[movie_prop_count].propID = kQTDataLocationPropertyID_CFStringNativePath;
movie_props[movie_prop_count].propValueSize = sizeof(cfpath);
movie_props[movie_prop_count].propValueAddress = (void*)&cfpath;
movie_props[movie_prop_count].propStatus = 0;
++movie_prop_count;
// make Movie active
movie_props[movie_prop_count].propClass = kQTPropertyClass_NewMovieProperty;
movie_props[movie_prop_count].propID = kQTNewMoviePropertyID_Active;
movie_props[movie_prop_count].propValueSize = sizeof(bool_true);
movie_props[movie_prop_count].propValueAddress = &bool_true;
movie_props[movie_prop_count].propStatus = 0;
++movie_prop_count;
// aquire Movie for our Movie file
NewMovieFromProperties( movie_prop_count, movie_props, 0, 0, &movie );
// invoke conversion dialog
ConvertMovieToFile( movie, 0, 0, 0, 'TVOD', 0, 0, flags, 0 );
// clean up
DisposeMovie( movie );
CFRelease( cfpath );
ExitMovies();
TerminateQTML();
...
If you are working on OS X only I would stick with the QTKit APIs because they are much higher level and generally easier to work with.
The general gist of what you want to do is:
Step Through each frame in a movie
Get a image representation for the current frame
Save the current frame's image to a file on disk
To step through the frames in a QuickTime movie, you can use the QTMovie class in QTKit to do this as follows:
- (void)dumpFramesWithMovie:(QTMovie*)movie toFolder:(NSString*)folderPath
{
[movie setIdling:NO]; // Don't idle the movie
[movie gotoEnd];
QTTime endTime = [movie currentTime];
[movie gotoBeginning];
// Number of frames counted so far
unsigned long numFrames = 0;
// Turn off the Movie's looping so we are quaranteed to stop
[movie setAttribute:[NSNumber numberWithBool:NO] forKey:QTMovieLoopsAttribute];
// Construct a Dictionary of to use when reading frames from a movie
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
[attributes setObject:QTMovieFrameImageTypeNSImage forKey:QTMovieFrameImageType];
while (true)
{
QTTime curTime = [movie currentTime];
if (QTTimeCompare(curTime, endTime) == NSOrderedSame)
{
// Reached end of file
break;
}
// Get the Current Frame as an NSImage
NSImage* image = [movie frameImageAtTime:curTime
withAttributes:attributes error:nil];
// Get the bitmap representation of this image
// NOTE: This code assumes the first image representation is a NSBitmapImageRep, which is true
// by default in OS X 10.5 and later.
// Production code should do error checking here.
NSBitmapImageRep *bitmap = [[image representations] objectAtIndex: 0];
// Construct a filename based upon the folder path and number of frames read so far
NSString* fileName = [NSString stringWithFormat:#"%#/frame%d.png", folderPath, numFrames];
// Get an PNG representation of this file
NSData *data = [bitmap representationUsingType: NSPNGFileType
properties: nil];
// Write to disk
[data writeToFile: fileName
atomically: NO];
// Step to the next Frame
[movie stepForward];
numFrames++;
}
[movie gotoBeginning];
}
#end
This code compiles but has not been fully tested.
One caveat with this approach is that MPEG-1 files will not decode properly on OS X 10.5 and earlier. This has been fixed as of 10.6 as far as I know. Also, if are writing a Windows application, you'll need to use the lower lever Quicktime-C APIs.
Be sure to check the following reference pages while working on this:
QTKit Application Programming Guide
QTKit Frequently Asked Questions
QTMovie Class Reference
Quickies for NSImage
NSBitmapImageRep Reference
NSImage Reference
These command line OSX utilities are really good at extracting the contents of a Quicktime movie without having to buy QTPro:
qt_tools
I usually just dump the decoded frames into a binary one after another and then use some YUV-Viewer to see if they look Ok. For that you have to know the exact color format and resolution of the decoded frames. If you have RGB, there are certainly also viewers for that.
UPDATE:
Link doesn't seem to work. You will have to google for a YUV-Viewer. Alternatively, you can buy one from Elecard.