|

|
SpectraCore FAQs
Install of SpectraWorks 2.4
I installed the latest version of SpectraWorks 2.4 but now cannot compile my
source code successfully because ChunkLoad.c needs the structure
SW_LoadFontData and it no longer exists. Why?
In SpectraWorks versions 2.4 and beyond, we changed to using iType for the font
engine. When using iType, the font must be loaded completely in one total
amount, not as chunks. The partial font loading functionality does not work the
same as the previous SpectraWorks versions. Therefore, any code that uses the
message EVENT_RESMGR_LOADFONT_DATA and the data structure SW_LoadFontData will
not be activated and should be removed.
Can SpectraWorks support Flash?
The SpectraWorks SDK currently does not contain a Flash viewer.
License and Version
How can the version numbers and system interoperability (or compatibility) with
SpectraBuilder workflow be controlled? We work on large GUI projects and there
is no way other than putting everything under VCS control. How much the GUI
tool’s project files are compatible with VCS is very important. A text based
project file would be helpful.
The SpectraBuilder project file itself is in binary format (the PRE file), but
on every Export that creates the BIN file there is also an XML file that’s
built which describes each widget and all of the attributes of the widget. The
XML file is very friendly for VCS systems, and any text-based DIFF utility can
show what changes were made from version-to-version. We and our customers
extensively use source control for SpectraWorks products, it’s very important.
What information is bound to Builder’s license key?
The key is locked to the machine (by using the IDs of internal hardware
components) that it is installed on and cannot be moved. Also changing the
date/time of the computer can invalidate the license.
How does time adjustment on the clock of my PC affect licensing of the
SpectraWorks SDK?
The SpectraWorks SDK uses a copy-protection method that creates a unique,
time-based key for a machine that it is installed on. Adjusting the clock in
any significant way is viewed by the licensing software as an attempt to get
around the license period and invalidates the machine’s current license.
Automatic time updating can trigger this lockout and we recommend that it be
removed from a system that has SpectraWorks installed. We have not found any
trouble with normal domain membership. If the domain controller pushes time
updates regularly, you will run into trouble.
The Registration Number of SpectraBuilder is used to generate the license key
upon initial installation. When the license expires, will the Registration
Number change so that this number gets used to produce to new license key?
No, immediately after a valid license key is installed, the Registration Number
changes to a new one. Therefore when the license expires, there is no change,
preventing the problem described from happening in the future.
Porting SpectraCore
Many embedded system designs do not have a file system. How can SpectraCore be
ported to systems without file systems?
One method is to place SpectraCore's BIN file into the source code as a global
array. It is recommended that after the BIN file is created, it be run through
a "binary to hex" converter program to change it into a header (.h) file and
'#include' it into one of your source files. Then use AppMgr_CreateInstance()
and pass a pointer to the first element of the array instead of a pointer to
the BIN file loaded from the file system.
There is a Windows command-line program called BIN2H that will do the
conversion, although the name of the array at the top of the resulting header
file will need to be fixed.
A problem may occur when making BIN files that are too large to compile. In this
case, another way must be found to place the BIN file into the ROM on the
system so it can be loaded or pointed to.
NOTE: SpectraCore does not directly change the BIN file at run-time; therefore a
BIN can be placed into actual ROM (or Flash ROM). SpectraCore will record any
run-time changes in a very small amount of RAM.
How does SpectraCore handle memory management?
SpectraCore is used in embedded environments where control of memory is
critical to avoid one part of the system disturbing another, and often there is
no effective Operating System memory management. SpectraCore requires the
typical memory management functionality - allocation, free, re-allocation, and
cleared allocation. However, it does not *require* the typical "malloc / free /
realloc / calloc" APIs. For each platform it can define the APIs to be used by
SpectraCore for memory management - consult the swstdlib.h file for your
platform's definitions of SW_MALLOC, SW_FREE, SW_REALLOC, and SW_CALLOC.
In a simulation environment such as Windows, SW_MALLOC is simply defined as
malloc(). In most SpectraCore ports, we use a SpectraWorks reference memory
manager to control a block of memory. This reference memory manager can be
easily configured to control the amount of memory that's used by SpectraCore,
and its APIs match typical memory management APIs. The pwmem.c/.h module
defines functions such as PWMEM_MallocMemory() and PWMEM_FreeMemory() to
replace the system memory management functions. Note that SpectraCore is built
with references to memory management APIs. To change these, SpectraCore must be
re-compiled. It is not possible to control these at the application level.
It's important to note that when using the pwmem.c/.h module, it is a
configurable replacement for "malloc". The first decision to make is how much
memory to give it - this memory cannot be expanded at run-time beyond the
initial size. The PW_MEMORY_BLOCK_SIZE define can be found at the top of
pwmem.c and can be set appropriately. The recommended starting amount is 2
megabytes; this can be fine-tuned by examining run-time statistics in the
memory manager. The next decision to make is how to allocate the memory block
that pwmem will manage in - either by a single call to the system "malloc" or
by a global array of data. The typical configuration is to use malloc, and can
be verified by examining the PWMEM_InitMemory() function. To change to a global
array of data, comment-out the reference to malloc and un-comment the
references to PWMemoryHeap.
Finally, be sure to initialize the pwmem.c/.h memory system by calling the
PWMEM_InitMemory() once at the beginning of the application, before making any
SpectraCore API calls such as AppMgr_CreateInstance().
Does SpectraWorks support 24-bit graphics format?
Occasionally, SpectraCore will need to be ported to a 24-bit graphics system.
Instead of using a 32-bit per pixel memory format such as XRGB, where X is an
unused byte, the 24-bits are packed into three bytes.
The problem with the 24-bit packed format is that it is slow because it requires
three bus cycles to read a pixel. Most systems cannot read a long word (32-bit)
value from an odd byte boundary, for example 0x80002003. In this example, with
a 32-bit per pixel memory format style, a long word is read from 0x80002000,
then from 0x80002004 to access pixels #0 and #1. With the 24-bit format, byte
reads must be performed from 0x80002000, 0x80002001, and 0x80002002 along with
shifting to place the RGB together into the same long word for operations.
Our recommended style of operation for 24-bit graphics systems is to run
SpectraCore in 32-bit mode. Then, in the "update" code that moves data from the
SpectraCore frame buffer to the hardware frame buffer, a single long word read
for the pixels can be done from the 32-bit mode frame buffer and then stored in
three sequential byte writes to the hardware frame buffer.
Performing the 32-bit to 24-bit conversion in the frame buffer update code gives
the minimum number of inefficient 24-bit pixel operations to occur.
Thus, you should use a 32-bit plug-in mode to export the resources and create a
32-bit BIN file. Then at run-time, be sure to give SpectraCore enough memory in
the frame buffer for 4 bytes per pixel.
What is needed from the platform provider in order to port SpectraCore to that
platform?
To make a SpectraCore platform port we need either a hardware reference
platform or the actual device in a development mode, and the complete software
development tools chain to run a program on the device. The development tools
chain means the C compiler as well as simple sample code to run a graphical
program on the device (just drawing a color to the display is enough). For the
user’s input, we’ll need that sample also – remote control, touch screen,
buttons, etc. In general, the hardware platform provider’s SDK is enough, with
some instructions on how to use it, and the samples. Note: The clearer the
samples are to show writing to the display and reading from the input, the
faster our port will happen.
Coding Applications
What needs to be done to initialize the OSD platform?
As part of the SpectraWorks SDK, samples are included to demonstrate the use of
applications using SpectraCore. Several of the samples have a file called osd.c
with a function called OSDPlatformInit(). This function should be called
immediately after AppMgr_CreateInstance(). Typically, this function will
perform the following:
-
Calculate the size of the frame buffer necessary for SpectraCore.
-
Allocate memory from the system heap (not the PWMEM heap) for that frame
buffer.
-
Inform SpectraCore of the memory location of the off-screen frame buffer.
SpectraCore will perform all drawing operations into this buffer.
-
Finally, but most importantly, hook the SpectraCore Global Event Handler to a
routine such as OSDPlatformUpdate(). This will allow OSDPlatformUpdate() to
receive an event when SpectraCore is done drawing a rectangle.
The following is the platform initialize routine from one of the samples. It is
similar to the update routines in the other samples:
| OSDPlatformInit() |
static SW_ERROR OSDPlatformInit(SW_INSTANCE hSWInstance)
{
BITMAPINFO bmi;
SW_UINT32 bytesInFrameBuffer;
SW_UINT32 i;
int nBitDepth = OSDMgr_getBitDepth(hSWInstance);
if (nBitDepth == 0)
{
OSDMgr_SetBitDepth(hSWInstance, BYTES_PER_PIXEL * 8);
OSDMgr_SetColorFormat(hSWInstance, BITMAP_RGB_8888);
}
OSDMgr_SetFrameSize(hSWInstance, PW_UI_OSD_WIDTH,
PW_UI_OSD_HEIGHT);
/* should only initialize this once */
if (g_hDC[BUF_TYPE_DISPLAY])
return SW_OSDMGR_ALREADY_INIT;
/* create some compatible DCs */
for (i = 0; i < BUF_TYPE_MAX; i++)
{
g_hDC[i] =
CreateCompatibleDC(GetDC(hDisplayHwnd));
if (g_hDC[i] == NULL)
return SW_OSDMGR_INIT_FAILED;
}
bytesInFrameBuffer = PW_UI_OSD_WIDTH * PW_UI_OSD_HEIGHT
* BYTES_PER_PIXEL;
/* create some device independent bitmaps. */
ZeroMemory(&bmi, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = PW_UI_OSD_WIDTH;
bmi.bmiHeader.biHeight = -PW_UI_OSD_HEIGHT;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = BYTES_PER_PIXEL * 8;
bmi.bmiHeader.biCompression = BI_RGB;
for (i = 0; i < BUF_TYPE_MAX; i++)
{
g_hBitmap[i] = CreateDIBSection(g_hDC[i], &bmi,
DIB_RGB_COLORS, &gBuffer[i], NULL, 0);
if (g_hBitmap[i] == NULL || gBuffer[i] == NULL)
{
MessageBox(g_hDisplayHwnd, TEXT("Error creating
DIB section"), NULL, MB_OK);
return SW_OSDMGR_INIT_FAILED;
}
/* select the DIB into the memory DC */
g_hOldBitmap[i] = SelectObject(g_hDC[i], g_hBitmap[i]);
memset(gBuffer[i], 0, bytesInFrameBuffer);
}
/* save pointer to frame buffer */
OSDMgr_SetFrameBuffer(hSWInstance, gBuffer[BUF_TYPE_DISPLAY]);
/* Hook the global drawing callback */
AppMgr_RegisterMainEvent(hSWInstance, OSDPlatformUpdate);
return SW_OK;
} |
What needs to be done to update the OSD platform?
As part of the SpectraWorks SDK, samples are included to demonstrate the use of
applications using SpectraCore. Several of the samples have a file called osd.c
with a function called OSDPlatformUpdate(). This routine should handle the
update and display of the hardware platform's frame buffer.
A call to AppMgr_Update() will send an event that triggers a call to
OSDPlatformUpdate(), which will draw to the on-screen frame buffers.
The following is the platform update routine from one of the samples. It is
similar to the update routines in the other samples:
| OSDPlatformUpdate() |
static SW_UINT32 OSDPlatformUpdate(SW_INSTANCE hInstance, SW_UINT32 ulEvent,
SW_UINT32 eventData)
{
RECT rect;
SW_RECT r_window;
SW_RECT frameRect;
SW_RECT *pClip;
if (ulEvent == EVENT_APPMGR_BEGIN_DIRTYRECT) return 0;
if (ulEvent != EVENT_APPMGR_END_DIRTYRECT)
{
return 0;
}
/* Get SpectraCore dimensions */
pClip = (SW_RECT *)eventData;
OSDMgr_GetFrameDims(hInstance, &frameRect);
/* Set up a faux clip rect, if we don't already have one */
if (pClip == NULL)
{
r_window.left = 0;
r_window.top = 0;
r_window.right = frameRect.right;
r_window.bottom = frameRect.bottom;
pClip = &r_window;
}
/* Tell Windows to draw the "hardware" frame buffer */
rect.top = pClip->top;
rect.bottom = pClip->bottom;
rect.left = pClip->left;
rect.right = pClip->right;
InvalidateRect(g_hDisplayHwnd, &rect, FALSE);
UpdateWindow(g_hDisplayHwnd);
return 0;
} |
What are the restrictions with the API call to AppMgr_MoveLayout()?
AppMgr_MoveLayout() moves a layout that's on-screen, or partially on-screen, to
another location on the screen. It will do the following:
-
Copy the data from one part of the SpectraCore frame buffer to another part of
the frame buffer;
-
Draw over areas that need to be restored; and
-
Draw areas that are moved from off-screen to on-screen.
It currently does not handle clipping to a parent widget's container, only to
the screen.
This routine should NOT be used if the layout contains any of the following:
-
Any transparent pixels
-
Alpha blending
-
Scaling
-
Perspective transformation
How does AppMgr_Layout() handle a layout that's moved from off-screen to
on-screen? How is this different from a call to PWidget_SetPos()?
AppMgr_MoveLayout() copies the pixels that are in the on-screen area of a
layout from the current position to the new position specified in the
AppMgr_MoveLayout() function call. If a layout is moved entirely within the
screen, this is very fast because there is no need to re-render (for example,
decode graphics, calculate and scale text, etc.). But if a layout is moved from
off-screen to on-screen, then the fraction that comes on-screen is drawn in an
identical way as PWidget_SetPos(). The disadvantage of AppMgr_MoveLayout() is
*not* screen area--the area is identical to PWidget_SetPos(). The disadvantage
is that there is no re-drawing, only copying. Hence, if a layout moves but
there are objects "below" it that can be seen through transparency or alpha
blending, then those areas will be *wrong*.
Is there an API provided to detect if a widget on the screen has been touched?
Currently there is no such function, but the following is an example of a
routine that can be written for your application. Note that this is for "touch
panel" or "mouse click" support.
| TouchPanelOver() |
/**
* This function gets the Widget ID that has been touched based on the
coordinates that are
* passed in as parameters.
*
* hSWInstance: The SpectraCore instance to search
* x: The x position
* y: The y position
*
* Return The widget ID that is under the x,y position passed in. If no
widget is found,
* WIDGET_UNKNOWN is returned.
*/
SW_WIDGETID TouchPanelOver(SW_INSTANCE hSWInstance, SW_SINT32 x, SW_SINT32 y)
{
SW_XY point;
SW_WIDGETID overWidget = WIDGET_UNKNOWN;
SW_WIDGETID guiLayout;
SW_WIDGETID layout;
SW_SINT32 currentLayoutIndex;
SW_SINT32 lastLayout = 0;
point.x = x;
point.y = y;
/* Get the number of layouts being displayed and search the widgets in all of
them to
* find the widget that has been touched. Start with the top layout on the
screen. */
for ( currentLayoutIndex = AppMgr_GetNumLayouts(hSWInstance) - 1;
currentLayoutIndex > =
lastLayout; --currentLayoutIndex )
{
/* Get the layout at the current index, do not
remove it from the stack. */
guiLayout = AppMgr_PeekLayout(hSWInstance,
currentLayoutIndex);
layout = guiLayout;
do
{
/* See what kind of widget was
touched and if there was actually a widget underneath. */
overWidget =
AppMgr_HitTest(hSWInstance, layout, point);
if ( (overWidget == guiLayout) ||
(overWidget == layout) )
{
overWidget =
WIDGET_UNKNOWN;
break;
}
/* If the widget is not a layout, we
found it!! */
if ( PWidget_GetType(hSWInstance,
overWidget) != WIDGET_LAYOUT )
break;
/* Adjust the position and keep
looking. */
layout = overWidget;
point.x -=
PWidget_GetPosX(hSWInstance, overWidget);
point.y -=
PWidget_GetPosY(hSWInstance, overWidget);
} while ( overWidget != WIDGET_UNKNOWN );
if ( overWidget != WIDGET_UNKNOWN ) break;
}
/* If we found a widget and the state of that widget is not disabled, then set
the focus to that widget and update the screen. */
if ( (overWidget != WIDGET_UNKNOWN) && !(PWidget_GetState(hSWInstance,
overWidget) & WIDGET_STATE_DISABLED))
{
/* return the widget id */
return overWidget;
}
return WIDGET_UNKNOWN;
} |
What does PLayout_SetScale() API do?
You can use SpectraBuilder to see the effects of the PLayout_SetScale() API by
changing the Scale attribute of a layout in the Layout Attributes. From that
you will see that the center point of the widget is maintained (not top-left).
You can also determine that the various base attributes of the widget are *not*
changed - width, height, and position. Setting the scale value using
PLayout_SetScale() to 100% (which is a 8.8 fixed-point number: 0x0100) will
return the size of the layout back to *exactly* the original size.
What is the difference between the following APIs - PWidget_CalcStringRect(),
PStaticText_GetStringRect(), and FontMgr_CalcStringRect()?
-
API PStaticText_GetStringRect()
- This API returns the widget's screen boundaries without respect to the text
inside.
-
PWidget_CalcStringRect()
- This API calculates the text's boundaries, not the widget's boundaries.
PWidget_CalcStringRect() uses FontMgr_CalcStringRect() to do its job.
-
FontMgr_CalcStringRect()
- This API uses the widget's boundaries and the attributes of the text to find
the resulting string's boundaries.
PWidget_CalcStringRect() is best for the typical application because it avoids
the application's usage of the more complex SW_FontBlit structure.
How can SpectraCore be used with double-buffered systems?
Some hardware platforms support only double-buffered operation. In this case,
the hardware displays from a frame buffer, the application makes changes to an
off-screen frame buffer, and then a single hardware operation switches between
the two buffers. In a very fast operation the entire screen is changed to show
the contents of the off-screen frame buffer, and the previously displayed
buffer is now writeable by the application.
Unfortunately, the contents of the frame buffer that becomes available after the
"switch" are "old". After updating new rectangles by copying from the
SpectraCore frame buffer to the off-screen frame buffer, and then switching,
the update function must perform the complete set of update copies to
synchronize the previously displayed buffer. The following steps are
recommended for systems that implement hardware double-buffering:
-
Have the SpectraCore Hardware Abstraction Layer that listens for the
EVENT_APPMGR_END_DIRTYRECT message make a list of these rectangles instead of
copying immediately.
-
Then, when the EVENT_APPMGR_END_UPDATE message is received, the rectangle list
should be processed and the regions should be copied from the SpectraCore frame
buffer to the off-screen frame buffer.
-
At this point, the frame buffer should be switched with the displayed frame
buffer.
-
Finally, the copy should be performed a second time.
-
In this way the displayed frame buffer and the off-screen frame buffer are
always kept "in-sync".
Of course there are other ways of accomplishing this synchronization An
alternative is to simply copy the entire contents of the SpectraCore frame
buffer to the off-screen buffer on receiving the EVENT_APPMGR_END_UPDATE
message. If you choose that style for simplicity you can ignore all
EVENT_APPMGR_END_DIRTYRECT messages.
What is the maximum number of widgets that SpectraWorks can handle?
65535 is the maximum number of widgets handled. An unsigned 16-bit number is
used as a unique ID.
What are your recommendations for design/code efficiency to improve the
application's performance?
-
If you have a GUI that uses various background images that overlap each other,
combine images and remove others in order to eliminate wasted decoding and
drawing.
-
For images that are large and underneath other images, place them into “cache”
so that they are not decoded every time an animation is used. The following
APIs can be used to handle cache:
-
SW_API void OSDMgr_SkinCache(SW_INSTANCE hInstance, SW_BOOL bOn);
-
SW_API SW_BOOL OSDMgr_SetCacheImage(SW_INSTANCE hInstance, SW_UINT32 nHash,
SW_BOOL cache);
-
SW_API SW_BMP_CONST * OSDMgr_CheckCacheImage(SW_INSTANCE hInstance, SW_UINT32
nIndex);
For long term maintenance of your design, use static text widgets instead of
bitmap widgets on your button widgets. For example, the “glow” effect of text
that you may create on a bitmap image can also be created using the attributes
of a static text. The advantage is that you can change the language of these
text strings in SpectraBuilder dynamically and that will be much easier,
smaller in size, and more flexible than using bitmap widgets.
How do I import image data that is read from external storage to the SpectraCore
engine? We want to load additional image data that is in a PNG file form an SD
card, and replace original button icons or bitmap images with them. This
functionality is useful when adding new button icons without firmware updates.
There are two parts to drawing external, dynamic image data in SpectraWorks.
First, you need to load the graphic and convert it into a simple bitmap of the
structure SW_BMP_CONST shown in osdmgr.h. The data structure has both the
information about the bitmap and the data (which follows immediately in the
m_pData array). If you choose a common format, such as PNG or BMP, you will
need to both decompress the data and colorconvert it to the correct color space
(x555 or 565). The *raw* data goes in the m_pData array.
The second part is drawing. You’ll need to use the OSDMgr_DrawBMP() API, but
you need to do it after the widget receives the EVENT_WIDGET_DRAW_END event.
When you register to receive the events on a widget using
AppMgr_RegisterEvent(), even the drawing begin and end events are sent to you.
Once a widget is done drawing, you can add what you like. You will need to set
the Button or Bitmap widget’s icon to “No Icon” before you take over the
drawing.
SpectraBuilder exports the binary and header files. But am I the one that needs
to write the control code, for example, swcap_main.c and swcap_submenu.c of the
SDK’s sample capabilities demo?
Once you’ve built the screens for your GUI using SpectraBuilder, the Export
step creates the binary and header files for the project. The Export step can
also generate “C” code that can be used framework for the application program
of your GUI. The code will need to be compiled using Visual Studio (2005 or
2010 will work) and can then be executed. This initial code can then be
modified for your product’s unique behavior. This feature is available in
SpectraWorks version 2.6. From the menu bar, select Project Properties, click
on the Export tab, and from here you will see the options for the project
starter.
Display
Why are the pixels on the edges of text not displayed correctly?
The pixels on the very edges of text are calculated at run-time by reading the
contents of the frame buffer at the drawing location, then blending that with
the color of the text using the gray-level from the character as a blending
ratio. This code lives in SpectraCore, and is represented as a series of
macros.
The following are macros that are defined for isolating the color channels of
the pixel formats supported by the OSD engine:
#define SW_RED_MASK32
#define SW_GREEN_MASK32
#define SW_BLUE_MASK32
#define SW_ALPHA_MASK32
|
0xFF
0xFF
0xFF
0xFF |
#define SW_GETALPHA32(pgc)
#define SW_GETRED32(pgc)
#define SW_GETGREEN32(pgc)
#define SW_GETBLUE32(pgc)
#define SW_RGB32(r,g,b)
#define SW_RGB32A(a,r,g,b)
#define SW_RGB32A_ALPHABLT(a,r,g,b)
|
(((pgc)>>24) & SW_ALPHA_MASK32)
(((pgc)>>16) & SW_RED_MASK32)
(((pgc)>>8) & SW_GREEN_MASK32)
((pgc) & SW_BLUE_MASK32)
(((r)<<16)|((g)<<8)|(b))
(((((((a)<<8)|(r))<<8)|(g))<<8)|(b))
(((((((a)<<8)|(r))<<8)|(g))<<8)|(b))
|
#ifdef SW_OSD_SUPPORT_16BIT
#define SW_ALPHA_MASK16
#define SW_RED_MASK16
#define SW_GREEN_MASK16
#define SW_BLUE_MASK16
|
0x01
0x1F
0x1F
0x1F
|
#define SW_GETALPHA16(pgc)
#define SW_GETRED16(pgc)
#define SW_GETGREEN16(pgc)
#define SW_GETBLUE16(pgc)
#define SW_RGB16(r,g,b)
#endif
|
((((pgc)>>15) & SW_ALPHA_MASK16))
(((pgc)>>10) & SW_RED_MASK16)
(((pgc)>>5) & SW_GREEN_MASK16)
((pgc) & SW_BLUE_MASK16)
(((r)<<10)|((g)<<5)|(b))
|
#if (defined(SW_OSD_SUPPORT_1BIT) || defined(SW_OSD_SUPPORT_2BIT)
|| defined(SW_OSD_SUPPORT_4BIT)
|| defined(SW_OSD_SUPPORT_8BIT)) |
#define SW_RED_MASK8
#define SW_GREEN_MASK8
#define SW_BLUE_MASK8
#define SW_ALPHA_MASK8
|
0xFF
0xFF
0xFF
0xFF
|
#define SW_GETALPHA8(pgc)
#define SW_GETRED8(pgc)
#define SW_GETGREEN8(pgc)
#define SW_GETBLUE8(pgc)
#define SW_RGB8A(a,r,g,b)
#endif
|
(((pgc)>>24) & SW_ALPHA_MASK8)
(((pgc)>>16) & SW_RED_MASK8)
(((pgc)>>8) & SW_GREEN_MASK8)
((pgc) & SW_BLUE_MASK8)
(((a)<<24)|((r)<<16)|((g)<<8)|(b))
|
Why do PNG images not display correctly using SpectraWorks? Some customers want
to use the Alpha value in PNG formatted images?
PNG format support in SpectraWorks is complete and accurate but does not match
the behavior of Photoshop or Flash. This is because SpectraWorks passes the
Alpha channel to the hardware and does not use it to blend between graphics in
the OSD. Other systems capture and handle the Alpha channel from PNG files
within the OSD, but have no method to pass pixel-by-pixel alpha to the
hardware. SpectraWorks does not implement pixel-by-pixel Alpha channel graphics
blending because it is very CPU sensitive.
As a comparison with Photoshop, remove the Alpha channel from the PNG image and
you will see the RGB only. This is what SpectraWorks uses.
Do PNG files (or any Alpha channel graphics) need to be used to show live-motion
video with pixel-bypixel control?
No. This affect can be achieved with SpectraWorks by defining a "chroma key".
The use of a chroma key is a technique based on the separation of colors in the
original images. A chroma key in this case will allow the live-motion video to
show through that color. SpectraWorks uses Background Color and Global
Transparent Color for this technique.
Background Color - The SpectraCore frame buffer is filled with a single
color called the "Background Color" before any widgets are drawn. If that color
is the platform's hardware transparent color (in other words you can see the
live-motion image through that one color), then the entire SpectraCore frame
buffer will "show" live motion until a widget is drawn into it. Widgets drawn
into the SpectraCore frame buffer would appear to be "floating" above
live-motion video.
Global Transparent Color (GTC) - The GTC is the specific color that
SpectraCore detects to avoid drawing a pixel. Therefore, if a bitmap is drawing
and the GTC is found, the pixel is not set. If the pixel is not set, then the
Background Color remains in that pixel (from the original clear of the
SpectraCore frame buffer). If an application wants to show live-motion in a
certain area, it needs to use the GTC in the graphic and set the Background
Color to the Chroma Key value.
Setting Background Color - To set Background Color using SpectraBuilder,
select the layout in which to set the background color and enter a value in the
Properties Window. To set the Background Color that is platform-specific, use
the run-time API OSDMgr_SetBackColor() after initializing the resources: void
OSDMgr_SetBackColor(SW_INSTANCE hinstance, SW_COLOR col);
In what order are the widgets in the display stack drawn? There are several
display stack API, such as AppMgr_PushLayout(), AppMgr_InserLayout(),
AppMgr_RemoveLayout(), AppMgr_PopLayout(), and AppMgr_PeekLayout().
The SpectraCore drawing algorithm is always the “painter’s algorithm”, which
means that the first widgets in the list will be drawn first. If a widget to be
drawn is a Layout, then the contents of the Layout will be drawn before moving
to the next widget in the list.
The display stack is a list of Layout widgets that will be drawn, the first one
in the list will be drawn completely, then the second, and so on. The
AppMgr_ShowLayout() API specifies a widget to be the only widget in the display
stack, so the most frequently used API call. To add a Layout to be drawn
*after* any existing Layouts that area already in the display stack, you could
use AppMgr_PushLayout().
For example, a dialog can be displayed by using AppMgr_PushLayout because the
dialog will become the last widget drawn. To remove the dialog, use
AppMgr_PopLayout().
Can SpectraWorks support displaying web content?
SpectraWorks does not support web content display directly. A customer that
wants to view Web content should obtain a web browser from an embedded systems
web browser company, such as Access in Japan or Opera in Europe. WebKit is a
possible option, but has a very large code and data footprint.
What are the requirements by SpectraWorks if the LCD module of the target device
is a characterbased display? Doesn’t SpectraWorks require a frame buffer?
The basic requirement is that the characters can be dynamically loaded (i.e.
they are not pre-defined and unchangeable). If any character’s data can be
changed, then we need to know the pixel dimensions, the character size in
pixels, and the color depth (or grayscale depth, or if it’s monochrome). We
also need to know the bandwidth to the display and any available API
documentation. It’s also important to understand the speed of the SOC’s CPU and
the amount of available RAM and ROM.
API Functions
What does the API function AppMgr_GetMaxLayouts() do?
This function gets the maximum number of Layouts on the currently displayed
Layout stack. A SpectraCore compile-time define creates this number and it can
be made larger or smaller by changing the swoptions.h file for the platform.
Windows and Target Device
How can the ‘touch input’ code be shared between Windows and the target device?
The functions SW_HandleMouseDown(), SW_HandleMouseUp(), and
SW_HandleMouseMove() are our reference application’s interface layer that is
the same in Windows as on the platform. The HAL function that is different
between platforms will call into the device independent layer.
Would an application that is tested on Windows work on the target device as it
is?
We expect that the Windows simulation will behave identically to the device
from a user-input and widget behavior perspective.
What would you recommend to share application code between Windows and target
device?
We strongly suggest sharing application code at this level between a Windows
simulation and the device. Only the HAL layer differs but the application code
that calls into the SpectraCore API will be identical.
Why does the Windows simulation fail to work on other machines?
In your application program you may have used a relative path to define the
location of your .BIN file. When you move the .EXE and .BIN files to another
machine you may have kept them in the same folder but the relative path may not
be the same as on the other machine. To avoid this issue, change the definition
to be just the file name. Also update Visual Studio’s working folder during the
Debug session to be the folder that contains the BIN file.
I want to transfer the GUI to the target device. Are the control programs, such
as main.c, devicespecific?
To transfer the GUI to the device, the GUI control code, such as swcap_main.c
and swcap_submenu.c of the SDK’s sample capabilities demo, are used on both the
Windows simulation and the device. The device-specific code that loads the BIN,
launches the application, and directly draws to the screen or receives user
input, is part of the HAL. We can perform the initial HAL port and then you can
modify it as their product matures. We provide a SpectraCore library for the
device’s CPU / tools chain.
Debugging
Is it possible to debug SpectraWorks to track an error?
SpectraCore is provided to our customers as a library with symbols, and it
supplies error reporting both as error codes as well as output diagnostics. In
standard contracts we do not supply source code, in order to protect our
algorithm Intellectual Property as well as to reduce version problems between
our customer and our development. In some situations we have agreed to supply
source code in Escrow in the case there is some problem that we cannot solve in
a timely manner, so that our customer will never be blocked due to our
inability to fix any problem.
How do I control the SpectraCore printout messages?
If you look at the config/swstdlib.h file you’ll find a macro called SW_TRACE.
In each platform’s HAL layer this could be defined differently. All SpectraCore
output messages use this macro. Inside the function that the macro is set to
would be the implementation of “printf(message)”. To turn off the messages,
just comment-out this line. No SpectraCore change is required.
Conversions
Project Conversion: We are using our own proprietary system . How easy is it to
convert a project from our current system?
We understand that most customers have proprietary systems and that conversion
to a completely new system is always difficult. In general, there’s always both
a learning curve as well as a product conversion curve in changing to any new
system, SpectraWorks is the same. But, we find that SpectraWorks can usually
leverage the existing graphical assets quickly and easily and with some MTI
assistance most customers are productive within 30-60 days of starting their
project conversion.
Image Conversion: Our target device is 16-bit color however we use 24-bit images
when working with SpectraBuilder. In this case, when does image conversion
happen? Does it happen on the target device when the project is finally
displayed, or it does it happen when Builder exports the resource file? When
bit depth is reduced, what algorithm is used? Nearest neighbor color? Is
dithering applied?
SpectraBuilder can use graphics with a different color depth (and even
different color space) than the target device. The selection of the output
device and color space in the SpectraBuilder Project’s Properties (F6 key)
allows for the choice of target platform. Most platforms have different color
modes they support, and MTI Engineering usually creates a new platform Plug-in
(DLL) for each unique device. The Plug-in controls the color conversion from
the SpectraBuilder internal 32-bit format (all images that come into
SpectraBuilder are up-converted to 32-bit) to the target device’s color space.
The default conversion is by color truncation. If the target color space is a
color palette, the nearest color is chosen. In the default Plug-ins, there is
not dithering applied. Customers may request that a dithering algorithm be
supplied when a new platform is being supported (and paid for). In the
SpectraBuilder preview mode, the custom platform dither algorithm will *not* be
visible.
I have a UI design that I used HTML to implement. Can SpectraWorks support a
conversion without me (the designer) having to make changes?
At this time we do not have a tool that converts from HTML to SpectraWorks. The
designer would use the same graphics artwork as HTML, but use SpectraBuilder to
create the SpectraWorks Widgets to implement the data.
|