How to add word wrapping to texts in Magick++ - c++

I am trying to add texts to images in Magick++ by doing so:
Method 1:
Magick::Image image(Magick::Geometry(800,800),Magick::Color("white"));
Magick::Color color(0,0,0,0);
image.font("Waree");
image.fontPointsize(36);
image.strokeColor(color);
image.fillColor(color);
image.annotate("HelloWorld!", NorthWestGravity);
Method 2:
Magick::Image image(Magick::Geometry(800,800),Magick::Color("white"));
Magick::Color color(0,0,0,0);
std::list<Magick::Drawable> text_draw_list;
text_draw_list.push_back(Magick::DrawableViewbox(0,0,image.columns(), image.rows()));
text_draw_list.push_back(Magick::DrawableFont("Waree", (Magick::StyleType)NormalStyle, 400, (Magick::StretchType)NormalStretch ));
text_draw_list.push_back(Magick::DrawablePointSize(36));
//Manual offsets
text_draw_list.push_back(Magick::DrawableText(0, 200, "HelloWorld!"));
text_draw_list.push_back(Magick::DrawableStrokeColor(color));
text_draw_list.push_back(Magick::DrawableFillColor(color));
image.draw(text_draw_list);
Method 1 calculates best offsets given the gravity but does not have any word wrapping if the text is out of bounds of the image.
Method 2 has Method 1's problem plus it assumes that the correct offsets have been calculated so the text is written at the correct position.
How do I add automatic word wrapping to either of the 2 methods but preferably to method 1?
P.S: ImageMagick has automatic word wrapping by using the caption option but I couldn't find caption in Magick++.
Edit: Ugly boundary control based on font size.
Magick::Image image(Magick::Geometry(800,800),Magick::Color("white"));
Magick::Color color(0,0,0,0);
image.font("Waree");
image.fontPointsize(36);
image.strokeColor(color);
image.fillColor(color);
std::string txt = "HelloWorld!";
Magick::TypeMetric typeMetrics;
double fontSize = 36;
image.fontTypeMetrics(txt, &typeMetrics);
while(fontSize > 0)
{
if(typeMetrics.textWidth() >= image.columns() || typeMetrics.textHeight() >= image.rows())
{
fontSize--;
image.fontTypeMetrics(txt, &typeMetrics);
}
}
image.annotate(txt, NorthWestGravity);

The best thing to do is read the caption.c source, and understand how word-wrapping is implemented. This would allow your application to have full control.
Another options would be to use PANGO: protocol. This would allow your content-author to have full control of word-wrapping, format, and many other font-display features.
But for the quickest approach, as you mentioned, caption already does this. But caption is not a method, but a file protocol.
#include <Magick++.h>
using namespace Magick;
int main(int argc, const char * argv[]) {
InitializeMagick(argv[0]);
Image words(Geometry(250,250), Color("white"));
words.backgroundColor(Color("lime")); // might not be needed.
words.font("Avenir-Heavy");
words.fillColor(Color("firebrick"));
words.strokeColor(Color("yellow"));
words.read("CAPTION:Hello World!"); // <---- CAPTION: protocol
words.write("/tmp/words.jpg");
return 0;
}

Related

Load icon from .DLL in wxWidgets

I am attempting to load a wxIcon in Windows by loading from a system DLL (as the mime system told me that the icon for such a file type was in the DLL), eg.
wxIcon icon;
icon.LoadFile("C:\\WINDOWS\\system32\\zipfldr.dll", wxICON_DEFAULT_TYPE);
This fails but I was wondering if there was any way in the codebase of loading this, other than resorting to native Win32 functions.
Also, if there are native Win32 functions, does anyone know what they are?
EDIT: I have tried the following with no success:
::wxInitAllImageHandlers();
wxMimeTypesManager manager;
wxFileType* type = manager.GetFileTypeFromExtension("sys");
wxIconLocation location;
if (type->GetIcon(&location))
{
// location is something like C:\WINDOWS\system32\imageres.dll
wxIcon icon;
if (!icon.LoadFile(location.GetFileName(), wxBITMAP_TYPE_ICON /*I have tried wxICON_DEFAULT_TYPE too*/))
{
// Failed!
}
}
EDIT 2: In response to VZ, I have tried the following with no success sadly:
::wxInitAllImageHandlers();
wxMimeTypesManager manager;
wxFileType* type = manager.GetFileTypeFromExtension("sys");
wxIconLocation location;
if (type->GetIcon(&location))
{
// location is something like C:\WINDOWS\system32\imageres.dll,
//with an appropriate index as retrieved by location.GetIndex(), which is -67.
wxIcon icon(location);
if (!icon.IsOk())
{
BREAK;
// Failed!
}
}
EDIT 3:
Thanks for everyone's help - works fine if I use wxBITMAP_TYPE_ICO instead of wxBITMAP_TYPE_ICON (notice the N), and also I was putting my test code in my app's constructor instead of in ::OnInit. It worked in OnInit but not in the constructor so that's a lesson learned!
Thanks everyone for the help and speedy responses, much appreciated as always.
It should work if you specify type wxBITMAP_TYPE_ICO.
The first argument to LoadFile() must specify the icon resource ID when using wxBITMAP_TYPE_ICO (which is indeed what you need to use when loading icons from files, and not resources of the current module), i.e. you're also missing the ;N part at the end, where N is the value returned by wxFileTypeInfo::GetIconIndex().
But to avoid dealing with this explicitly, you should just use wxFileType::GetIcon() and construct wxIcon from the wxIconLocation filled in by it.
For example, this:
diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index 0d91f7fc75..3623aacc56 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
## -123,6 +123,12 ## bool MyApp::OnInit()
if ( !wxApp::OnInit() )
return false;
+ wxIcon icon(wxIconLocation(R"(c:\Windows\system32\imageres.dll)", -67));
+ if ( icon.IsOk() )
+ {
+ wxLogMessage("Loaded icon of size %d*%d", icon.GetWidth(), icon.GetHeight());
+ }
+
// create the main application window
MyFrame *frame = new MyFrame("Minimal wxWidgets App");
shows the expected message about loading the icon of size 32 by 32.

How to load gif using wxWidgets c++?

I need your help! Im currently really new to wxWidgets as a uni student. I am trying to load a .gif file using wxWidgets. I tried using the code below... but it only loads 1 frame, it doesn't move/ change to the other frames, it's basically a still picture. The file is .gif extension, and it has 3 frames or so. The location of the image is already correct. Help would be much appreciated!
Thank you
#include "ImageWindow.h"
#include <wx/stdpaths.h>
#include <wx/filename.h>
BEGIN_EVENT_TABLE(ImageWindow, wxWindow)
EVT_PAINT(ImageWindow::OnPaint)
END_EVENT_TABLE()
ImageWindow::ImageWindow(wxFrame *parent)
: wxWindow(parent, wxID_ANY)
{
this->SetBackgroundColour(wxColour(*wxWHITE));
wxImageHandler *gifLoader = new wxGIFHandler();
wxImage::AddHandler(gifLoader);
this->LoadPotatoBitmap();
}
ImageWindow::~ImageWindow()
{
delete potatoBitmap;
}
void ImageWindow::LoadPotatoBitmap()
{
wxStandardPaths &stdPaths = wxStandardPaths::Get();
wxString fileLocation = stdPaths.GetExecutablePath();
wxImage image(wxT("A:\\Projects\\TestGif\\Assets\\Kuning.gif"),
wxBITMAP_TYPE_GIF);
potatoBitmap = new wxBitmap(image);
}
void ImageWindow::OnPaint(wxPaintEvent &event)
{
wxPaintDC pdc(this);
if (potatoBitmap != nullptr)
{
pdc.DrawBitmap(*potatoBitmap, wxPoint(150, 100), true);
}
}
You are not specifying the index of the image in the constructor and that's why you see the default one as you can see in the wxWdigets documentation:
wxImage::wxImage ( const wxString & name,
wxBitmapType type = wxBITMAP_TYPE_ANY,
int index = -1
)
index Index of the image to load in the case that the image file contains multiple images. This is only used by GIF, ICO and TIFF handlers. The default value (-1) means "choose the default image" and is interpreted as the first image (index=0) by the GIF and TIFF handler and as the largest and most colourful one by the ICO handler.
But, you should also consider wxAnimationCtrl (see this sample)
Use wxAnimationCtrl for playing gif animations
or
Use extract each frame from the gif image and draw one by one using wxTimer.

MFC CControlBar

How do you figure out/determine (either from a control bar, or from the frame it is attached to) which side of the frame a CControlBar is attached to?
I know you can:
determine whether a controlbar is floating via BOOL IsFloating( ) const;
tell a controlbar which side of a frame it is allowed to connect to CBRS_ALIGN_TOP, AFX_IDW_DOCKBAR_TOP
But I don't know how to retrieve which side it has been docked to. Hope there is a method like CurrentlyDockedTo() which would return either CBRS_ALIGN_TOP, AFX_IDW_DOCKBAR_TOP ...
I am looking for the fastest way to figure out how much gray space is left in the main window ... the size of the gray rectange
You should be able to use GetBarStyle:
https://msdn.microsoft.com/en-us/library/6y1e7ff1.aspx
I found a very simple solution to my question. Exactly the answer I needed. The initial hint which led me on the correct path was found in the following post:
Detecting when a CControlBar's docking state has changed
The code which I was asking for was the following:
CPtrList& list = this->m_listControlBars;
POSITION pos = list.GetHeadPosition();
int total_cntrl_bars_found = 0;
while(pos)
{
CControlBar* pBar = (CControlBar*)list.GetNext(pos);
if(pBar)
{
if(!pBar->IsFloating())
{
total_cntrl_bars_found++;
int total_matched_styles = 0;
DWORD bar_style = pBar->GetBarStyle();
if(bar_style & CBRS_ORIENT_VERT)
{
// Then the bar is vertially oriented
// Will additionally also pass either the
// right oriented or left oriented check depending
total_matched_styles++;
}
if(bar_style & CBRS_ORIENT_HORZ)
{
// Then the bar is vertially oriented
total_matched_styles++;
}
if(bar_style & CBRS_ALIGN_RIGHT)
{
// Then the bar is right aligned
total_matched_styles++;
}
if(bar_style & CBRS_ALIGN_LEFT)
{
// Then the bar is left aligned
total_matched_styles++;
}
// There is also a check for top align
// and bottom aligned
}
}
}
here is some more info on GetBarStyle()
https://msdn.microsoft.com/en-us/library/6y1e7ff1.aspx

c++ draw images on bitmap and save

//background feel free to skip
I am creating a animated clock for my Windows desktop background. Basically I create a bmp image with code using pre-drawn images (the numbers of the clock) then a save the bmp image and set the desktop background to that image. I tried using c# and .Net but inorder to set the desktop background I have to call a WinApi function (SystemParametersInfo). Calling this function from c# takes almost a second. Too long for an animation.
So now I want to do the same except in c++, I hope calling SystemParametersInfo will be faster from unmanaged code. EDIT:I used c# to create the bmp and c++ to set the desktop background and it is faster
//the question
I created a Win32 console project using Visual Studio 2012, and I managed to embed the pre-drawn images as resources. Now I need to combine the images onto a single bitmap and save it to the hdd. It has been four years since I last programmed in c++ so I have no idea how to draw a image and save it.
The code I found when googling all have to do painting to the screen, which I obviously don't want to do.
So how do create a bitmap, draw a resource image (also a bitmap) on it, and save it all in c++?
Thanks for any assistance.
This question is more about Windows API than about C++.
If you want to use Windows API, refer to GDI+:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms533798.aspx
.NET Framework wraps GDI+, so classes may be familiar for you just in C++ and not in C# with manual memory management, etc.
There are also some other libraries that can manipulate images. Personally me like GD, a C-style images manipulation library with many languages bindings.
https://bitbucket.org/libgd/gd-libgd/downloads
However, as always with Open Source, you will have to build it youself togeather with dependencies. So, probably GDI+ is the best.
As it turns out Win32 (c++) code is quick at changing the desktop background (under 20ms on i5 3.2ghz), where as the managed C# code takes anywhere from 500 to 3000ms. However, the unmanaged c++ code takes forever to draw the image (300 to 1500ms). So what I did was make two programs that work together. The managed C# program creates the image (under 20ms) and then saves it. The unmanaged c++ sets the saved image as the desktop background.
C#
static void Main(string[] args)
{
//the images positions where calculated manually and hard coded
//first image positoon
//X:532
//Y:335
Bitmap TheImage = new Bitmap(1366, 768);
Graphics G = Graphics.FromImage(TheImage);
DateTime DTNow = DateTime.Now;
while (true)
{
//get the time
DTNow = DateTime.Now;
//draw the canvas
G.DrawImage(Resources.canvas, 0, 0,1366,768);
//draw the first image of the hour
G.DrawImage(GetImage(DTNow.Hour,0),532,330,174,217);
//draw the second image of the hour
G.DrawImage(GetImage(DTNow.Hour, 1), 711, 330, 174, 217);
//draw the colon
if (DTNow.Second % 2 == 0) G.DrawImage(Resources.aColon, 890, 365,57,147);
//draw the first digit of the minute
G.DrawImage(GetImage(DTNow.Minute, 0), 952, 330, 174, 217);
//draw the second digit of the minute
G.DrawImage(GetImage(DTNow.Minute, 1), 1131, 330, 174, 217);
//save the file
try
{
File.Delete("C:\\background.bmp");
TheImage.Save("C:\\background.bmp", ImageFormat.Bmp);
}
catch
{
}
//calculate sleep time and sleep until next second
DTNow = DateTime.Now.AddSeconds(1);
DateTime NextSecond = new DateTime(DTNow.Year,DTNow.Month,DTNow.Day, DTNow.Hour,DTNow.Minute, DTNow.Second,500);
DTNow = DateTime.Now;
System.Threading.Thread.Sleep((int)NextSecond.Subtract(DTNow).TotalMilliseconds);
}
}
static Bitmap GetImage(int Number, int Index)
{
string NS = Number.ToString();
if (NS.Length < 2) NS = "0" + NS;
char[] digits = NS.ToCharArray();
switch (digits[Index])
{
case '1': { return Resources.a1; }
case '2': { return Resources.a2; }
case '3': { return Resources.a3; }
case '4': { return Resources.a4; }
case '5': { return Resources.a5; }
case '6': { return Resources.a6;}
case '7': { return Resources.a7;}
case '8': { return Resources.a8;}
case '9': { return Resources.a9; }
default: { return Resources.a0; }
}
}
}
c++
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd)
{
while(true){
SystemParametersInfo(SPI_SETDESKWALLPAPER,0, L"C:\background.bmp", SPIF_UPDATEINIFILE);
int MS = (int)(((long)floor((long)clock()/(long)CLOCKS_PER_SEC)*1000l+1000l)-((long)clock()));
if(MS<=1000 && MS>0){
std::this_thread::sleep_for(std::chrono::milliseconds(MS));
}
else
{
}
}
return 0;
}

Changing color of a specific character in an item in CListCtrl in MFC

I have a CListCtrl and I need to change the color of A SPECIFIC character/set of characters (which I choose by comparison) from the text of every cell in the list.
I know how to change the color of the entire text of the cell when I find the character/set of characters (by using 'strstr' command), but I can't find an example which shows how to change ONLY the character/set of characters.
Here is a sample of my code:
void Agenda::OnCustomdrawMyList( NMHDR* pNMHDR, LRESULT* pResult )
{
NMLVCUSTOMDRAW* pLVCD = (NMLVCUSTOMDRAW*)pNMHDR;
*pResult = CDRF_DODEFAULT;
if (CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
{
*pResult = CDRF_NOTIFYITEMDRAW;
return;
}else if (CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
{
*pResult = CDRF_NOTIFYSUBITEMDRAW;
return;
}else if ( (CDDS_SUBITEM | CDDS_ITEMPREPAINT) == pLVCD->nmcd.dwDrawStage )
{
// So right now I am in the stage where a SUBITEM is PREPAINTED
int nItem = pLVCD->nmcd.dwItemSpec;
int nSubItem = pLVCD->iSubItem;
char a[100];
listControl.GetItemText(nItem,nSubItem,a,100);
COLORREF textColorFound, textColorDefault;
textColorDefault = RGB(0,0,0);
pLVCD->clrText = textColorDefault;
char* startingFrom;
if( (startingFrom = strstr(a,filterText)) != NULL ) {
// Could I set a pointer here or something like that so
// the coloring could start only from 'startingFrom'
// and stop at 'strlen(filterText)' characters?
textColorFound = RGB(205,92,92);
pLVCD->clrText = textColorFound;
}
*pResult = CDRF_DODEFAULT;
}
}
listControl is the variable for my CListCtrl
the other things are pretty self-explanatory
No, you cannot do this. What you will have to do is custom-draw the text in question. This will be tricky because you will have to do it with two different calls, between which you will have to manually adjust the color and the drawing location to account for the intercharacter spacing etc. And you better hope that you don't need to do multi-line output.
Take a look at the article Neat Stuff to Do in List Controls Using Custom Draw by Michael Dunn on CodeProject to get some ideas on how to proceed.
Alternatively, if you can use the Toolkit Pro toolkit from CodeJock you can leverage their "XAML" support (I use quotes because it's not really XAML, but their own implementation of a subset of XAML) and let them do all the hard work.
Digging on the same issue; But I wouldn't go so far as modifying/adding to the default Windows behaviour for painting strings... apparently that would be the endpoint of having it owner-drawn.(aici am murit si eu :).