I am trying to use the GraphicsPath::AddString() method of GDI+ in my libcinder project.
The idea is to create a path of a letter/glyph via the mentioned method and later pass that to gl::draw() and box2d's b2FixtureDef. The goal is create falling letters that show an exact collision behaviour.
However the following example taken from learn.microsoft.com throws several errors at me.
#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/Rand.h"
#include <Box2D/Box2D.h>
#include <gdiplus.h>
#pragma comment (lib, "gdiplus.lib")
using namespace Gdiplus;
using namespace ci;
using namespace ci::app;
using namespace std;
// ...
void MyApp::draw()
{
FontFamily fontFamily(L"Times New Roman");
GraphicsPath path;
// const WCHAR
// Status AddString(
// IN const WCHAR *string,
// IN INT length,
// IN const FontFamily *family,
// IN INT style,
// IN REAL emSize, // World units
// IN const PointF &origin,
// IN const StringFormat *format
//)
path.AddString(
L"Hello World",
-1, // NULL-terminated string
&FontFamily("Arial"),
FontStyleRegular,
48,
PointF(50.0f, 50.0f),
NULL);
}
There are several issues with my code that just cant get fixed... My project's target platform version is 8.1 and the platform toolset is Visual Studio 2015 (v140). The headers are there and can be browsed to when hitting F12.
FontFamily fontFamily(L"Times New Roman");
"Cannot initialize local variable 'fontFamily' of type 'FontFamily'
with lvalue of type 'wchar_t const[16]'
GraphicsPath path;
"No default constructor exists for class "GraphicsPath""
path.AddString(...)
"class 'GraphicsPath' has no member 'AddString'"
Any help is very appreciated. I have spent hours with this issues with zero progress.
After searching high and low I figured it out. I was missing a couple of includes. But to be honest, I still don't really understand, why the compiler complained with that specific message...
The following does compile for me and produces the path coordinates for the letter "A".
// other includes
#include <windows.h>
#include <ObjIdl.h>
#include <minmax.h>
#include <gdiplus.h>
using namespace Gdiplus;
using namespace ci;
using namespace ci::app;
#pragma comment (lib, "Gdiplus.lib")
// ...
void MyApp::setup()
{
// ...
GraphicsPath p(FillModeAlternate);
FontFamily fontFamily(L"Arial");
if (p.AddString(L"A", -1, &fontFamily, FontStyleRegular, 48, PointF(0.0f, 0.0f), NULL) != Status::Ok)
{
std::cout << "Error while adding points" << std::endl;
}
PointF points[64];
if (p.GetPathPoints(points, sizeof(points)) != Status::Ok)
{
std::cout << "Error while getting points" << std::endl;
}
}
Related
It's been years since I used C++ and so I'm very rusty. I'm trying to test out the Geos library, but I'm unable to get a simple Hello World example to compile
https://libgeos.org/usage/download/
This is what I tried:
I downloaded and extracted the files
Created a new C++ project in Visual Studio
Added the headers folder into the Visual Studio Include Directories for the project.
Then I tried to use the library in my main.cpp:
#include <geos/geom/PrecisionModel.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/CoordinateSequenceFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/GeometryFactory.h>
#include <iostream>
#include <memory>
geos::geom::Polygon * MakeBox(double xmin, double ymin, double xmax, double ymax) {
std::unique_ptr<geos::geom::PrecisionModel> pm(new geos::geom::PrecisionModel());
geos::geom::GeometryFactory::unique_ptr factory = geos::geom::GeometryFactory::create(pm.get(), -1);
geos::geom::CoordinateSequence* temp = factory->getCoordinateSequenceFactory()->create((std::size_t)0, 0);
temp->add(geos::geom::Coordinate(xmin, ymin));
temp->add(geos::geom::Coordinate(xmin, ymax));
temp->add(geos::geom::Coordinate(xmax, ymax));
temp->add(geos::geom::Coordinate(xmax, ymin));
//Must close the linear ring or we will get an error:
//"Points of LinearRing do not form a closed linestring"
temp->add(geos::geom::Coordinate(xmin, ymin));
geos::geom::LinearRing* shell = factory->createLinearRing(temp);
//NULL in this case could instead be a collection of one or more holes
//in the interior of the polygon
return factory->createPolygon(shell, NULL);
}
int main() {
geos::geom::Polygon* box = MakeBox(0, 0, 10, 10);
std::cout << box->getArea() << std::endl;
delete box; //Important to avoid memory leaks
}
I'm getting multiple errors, but they all seem to indicate that the library is not loaded correctly
Severity Code Description Project File Line Suppression State Error
(active) E0135 class "geos::geom::GeometryFactory" has no member
"unique_ptr" TestGeos C:\TestGeos\TestGeos.cpp 15
What am I missing in order to use the library?
I am trying to learn the gdiplus windows API, and in particular how to use GraphicsPath to get points from different shapes. I noticed that I could never get anything to appear from microsoft's example code, so I tried to see how many points were actually in a GraphicsPath like this:
#include <windows.h>
#include <gdiplus.h>
#include <iostream>
//use gdiplus library when compiling
#pragma comment( lib, "gdiplus" )
using namespace Gdiplus;
VOID GetPointCountExample()
{
// Create a path that has one ellipse and one line.
GraphicsPath path;
path.AddLine(220, 120, 300, 160);
// Find out how many data points are stored in the path.
int count = path.GetPointCount();
std::cout << count << std::endl;
}
int main()
{
GetPointCountExample();
}
This always returned a count of 0. Why is this?
I have tried compiling with mingw-64 and Visual Studio with the same result.
I also tried printing out the Gdiplus::Status returned from this:
GraphicsPath path;
int stat = path.StartFigure();
std::cout << stat << std::endl;
Which printed a status of 2, "InvalidParameter" even though StartFigure doesn't take parameters.
Ahh read more documentation and found this: The GdiplusStartup function initializes Windows GDI+. Call GdiplusStartup before making any other GDI+ calls
https://learn.microsoft.com/en-us/windows/win32/api/Gdiplusinit/nf-gdiplusinit-gdiplusstartup
This code works:
#include <windows.h>
#include <gdiplus.h>
#include <iostream>
//use gdiplus library when compiling
#pragma comment( lib, "gdiplus" )
using namespace Gdiplus;
VOID GetPointCountExample()
{
// Create a path that has one ellipse and one line.
GraphicsPath path;
path.AddLine(0, 0, 0, 1);
// Find out how many data points are stored in the path.
int count = path.GetPointCount();
std::cout << count << std::endl;
}
int main()
{
//Must call GdiplusStartup before making any GDI+ calls
//https://learn.microsoft.com/en-us/windows/win32/api/Gdiplusinit/nf-gdiplusinit-gdiplusstartup
ULONG_PTR token;
GdiplusStartupInput input;
input.GdiplusVersion = 1;
input.SuppressBackgroundThread = false;
GdiplusStartup(&token, &input, NULL);
GetPointCountExample();
//Shutdown GDI+ when finished using
GdiplusShutdown(token);
}
I am new to C++ and i am getting error like
error: no matching function for call to 'FaceDetector::FaceDetector(std::__cxx11::string)'
FaceDetector fd(string(DEFAULT_CASCADE_PATH));
and i am attaching my code and error log how to fix this please guide me
#define DEFAULT_CASCADE_PATH "cascades/haarcascade_frontalface_default.xml"
#define ORIGINALS_LIST "obama_raw/list"
#define OUTPUT_DIR "obama_faces"
#define OUTPUT_LIST "list"
#define FACE_SIZE Size(150,150)
#include <cstdlib>
#include <fstream>
#include "cv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "FaceDetector.h"
using namespace std;
using namespace cv;
void read_input_list(const string &list_path, vector<Mat> &images) {
ifstream file(list_path.c_str());
string path;
while (getline(file, path)) {
images.push_back(imread(path));
}
}
int main(int argc, char** argv) {
FaceDetector fd(string(DEFAULT_CASCADE_PATH));
vector<Mat> raw_faces;
ofstream out_list(format("%s/%s", OUTPUT_DIR, OUTPUT_LIST).c_str());
read_input_list(string(ORIGINALS_LIST), raw_faces);
int img_c = 0; //images counter
//now detect the faces in each of the raw images:
for (vector<Mat>::const_iterator raw_img = raw_faces.begin() ; raw_img != raw_faces.end() ; raw_img++){
vector<Rect> faces;
//detect faces in the image (there should be only one):
fd.findFacesInImage(*raw_img, faces);
//cut each face and write to disk:
for (vector<Rect>::const_iterator face = faces.begin() ; face != faces.end() ; face++){
int edge_size = max(face->width, face->height);
Rect square(face->x, face->y, edge_size, edge_size);
Mat face_img = (*raw_img)(square);
//resize:
resize(face_img, face_img, FACE_SIZE);
//write to disk:
string face_path = format("%s/%d.jpg", OUTPUT_DIR, img_c++);
imwrite(face_path,face_img);
out_list << face_path << endl;
}
}
out_list.close();
return 0;
}
and i am attaching my error log.Please can any one help.
Thanks in advance
Error : https://i.stack.imgur.com/RZXXK.jpg
From GCC 5, A new ABI is enabled by default. In that new ABI, std::__cxx11 namesapce was introduced.
According to your error message, It seems that your program and OpenCV library you want to link with were build with different GCC version, which made incompatible binary.
For more information, you can read the following page:
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
I have a large C++ game project in which I want to add support for Xbox One controllers. I tried using the Windows.Gaming.Input namespace. However, it seems that this is only available for UWP projects. Is this true?
If this is the case, would it be easy to port an existing SDL engine to UWP?
You can call into Windows.Gaming.Input just fine from desktop applications - not sure where you got the idea that it's only available to UWP applications. Just include the header and use it. Here's the sample code for printing button states on all the gamepads:
#include <assert.h>
#include <cstdint>
#include <iostream>
#include <roapi.h>
#include <wrl.h>
#include "windows.gaming.input.h"
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::Gaming::Input;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
#pragma comment(lib, "runtimeobject.lib")
int main()
{
auto hr = RoInitialize(RO_INIT_MULTITHREADED);
assert(SUCCEEDED(hr));
ComPtr<IGamepadStatics> gamepadStatics;
hr = RoGetActivationFactory(HStringReference(L"Windows.Gaming.Input.Gamepad").Get(), __uuidof(IGamepadStatics), &gamepadStatics);
assert(SUCCEEDED(hr));
ComPtr<IVectorView<Gamepad*>> gamepads;
hr = gamepadStatics->get_Gamepads(&gamepads);
assert(SUCCEEDED(hr));
uint32_t gamepadCount;
hr = gamepads->get_Size(&gamepadCount);
assert(SUCCEEDED(hr));
for (uint32_t i = 0; i < gamepadCount; i++)
{
ComPtr<IGamepad> gamepad;
hr = gamepads->GetAt(i, &gamepad);
assert(SUCCEEDED(hr));
GamepadReading gamepadReading;
hr = gamepad->GetCurrentReading(&gamepadReading);
assert(SUCCEEDED(hr));
std::cout << "Gamepad " << i + 1 << " buttons value is: " << gamepadReading.Buttons << std::endl;
}
return 0;
}
I have a LPCSTR that I want to convert to std::string or char*.
LPCSTR strName;
_tprintf(_T("%s\n"), strName);
I'm trying to get all the audio equipment on the computer and displayed, but to get the LPCSTR type of direct output is garbled, use the above code to output the correct results.
Is there a way to save the correct output?
The following is the complete code:
Add a dependency to the property:
comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;odbc32.lib;odbccp32.lib
ListSoundDev.h
#ifndef _LISTSOUNDDEV_HEAD_
#define _LISTSOUNDDEV_HEAD_
#include<tchar.h>
#include <dshow.h>
#include<iostream>
#include<vector>
#include<mmsystem.h>
#include<mmreg.h>
#include<dsound.h>
#pragma comment(lib, "strmiids.lib")
#pragma comment(lib, "Quartz.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dsound.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "strmiids")
using namespace std;
typedef struct _DevItem
{
LPCSTR strName;
GUID guid;
} DevItem;
#endif
main.cpp
#include"ListSoundDev_head.h"
std::vector<DevItem> m_CapDevices;
BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)
{
std::vector<DevItem> *pLst = (std::vector<DevItem> *) lpContext;
if (pLst)
{
DevItem item;
memset(&item, 0, sizeof(item));
item.strName = lpcstrDescription;
if (lpGuid)
item.guid = *lpGuid;
else
item.guid = GUID_NULL;
pLst->push_back(item);
return TRUE;
}
return FALSE;
}
int main()
{
std::vector<DevItem>::iterator it;
HRESULT hr = S_OK;
setlocale(LC_ALL, "chs");
hr = DirectSoundCaptureEnumerate((LPDSENUMCALLBACKW)DSEnumCallback, (LPVOID)&m_CapDevices);
for (it = m_CapDevices.begin(); it != m_CapDevices.end(); it++){
_tprintf(_T("%s\n"), it->strName);//output correct
printf("%s\n",it->strName);//output error
std::cout << it->strName << std::endl;//output error
}
}
Expected output:
麦克风 (Realtek High Definition Au
Actual output:
KQ螛
Expected output:
Realtek Digital Input (Realtek
Actual output:
R
How can I that printf() or std::cout can directly output the correct results?
Thank you very much for your answer, I have solved this problem.
The solution is to use the following code to convert.
The character set is Unicode.
char newStr[100];
wcstombs(newStr, (wchar_t*)it->strName, 100);
printf("newStr=%s\n", newStr);
The character set is Multibyte
printf("%s\n", it->strName);
However, when I write this program in the C + + console to obtain the name of the audio device for the microphone (Realtek High Definition Au, but in MFC using this code to get the device name for the microphone (Realtek High Definition Audio) What is the reason?