[mapguide-commits] r7935 - in trunk/MgDev/Desktop: MgDesktop/Services/Rendering UnitTest

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Nov 27 04:35:03 PST 2013


Author: jng
Date: 2013-11-27 04:35:03 -0800 (Wed, 27 Nov 2013)
New Revision: 7935

Modified:
   trunk/MgDev/Desktop/MgDesktop/Services/Rendering/LegendPlotUtil.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Rendering/LegendPlotUtil.h
   trunk/MgDev/Desktop/UnitTest/TestRenderingService.cpp
   trunk/MgDev/Desktop/UnitTest/TestRenderingService.h
Log:
#2380, #2379: Port fixes to mg-desktop

Modified: trunk/MgDev/Desktop/MgDesktop/Services/Rendering/LegendPlotUtil.cpp
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Rendering/LegendPlotUtil.cpp	2013-11-27 11:55:44 UTC (rev 7934)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Rendering/LegendPlotUtil.cpp	2013-11-27 12:35:03 UTC (rev 7935)
@@ -93,6 +93,10 @@
     textDef.halign() = RS_HAlignment_Left;
     textDef.valign() = RS_VAlignment_Base;
 
+    //for convenience compute legend bitmap size in plot units (inches, mm, pixels, whatever)
+    double dIconWidth = ((double)bitmapPixelWidth / bitmapDpi)*convertUnits;
+    double dIconHeight = ((double)bitmapPixelHeight / bitmapDpi)*convertUnits;
+
     // Get the layer info
     double x = legendOffsetX + legendSpec->GetMarginLeft();
     double y = legendOffsetY + legendSpec->GetPaperHeight() - legendSpec->GetMarginTop() - legendFontHeightMeters*M_TO_IN*convertUnits;
@@ -101,63 +105,54 @@
     //for icon and label from the bottom up
     y -= legendSpacing * convertUnits;
 
+    // Compile the necessary information needed to avoid repeated linear searches for this information
+    LayerGroupChildMap groupChildren;
+    VisibleLayerCountMap visibleLayers;
+    CompileInformation(map, visibleLayers, groupChildren);
+
     // Add legend entries for layers that do not belong to a group
-    ProcessLayersForLegend(map, scale, NULL, x, y, textDef, dr, legendSpec, legendOffsetY, convertUnits);
+    ProcessLayersForLegend(map, scale, NULL, x, y, textDef, dr, legendSpec, legendOffsetY, convertUnits, visibleLayers, groupChildren);
+}
 
-    // do layer groups
-    Ptr<MgLayerGroupCollection> mggroups = map->GetLayerGroups();
+void MgdLegendPlotUtil::CompileInformation(MgdMap* map, VisibleLayerCountMap& visibleLayers, LayerGroupChildMap& groupChildren)
+{
     Ptr<MgLayerCollection> layers = map->GetLayers();
+    Ptr<MgLayerGroupCollection> groups = map->GetLayerGroups();
 
-    // iterate over groups and draw each group's layers
-    for (int k = 0; k < mggroups->GetCount(); k++)
+    for (INT32 i = 0; i < layers->GetCount(); i++)
     {
-        Ptr<MgLayerGroup> mggroup = mggroups->GetItem(k);
+        Ptr<MgLayerBase> layer = layers->GetItem(i);
+        if (!layer->IsVisible()) //Not visible
+            continue;
 
-        // Count number of visible layers in this group.
-        bool hasVisibleLayers = false;
-        for (int l = 0; l < layers->GetCount(); l++)
-        {
-            Ptr<MgLayerBase> layer = layers->GetItem(l);
-            Ptr<MgLayerGroup> layerGroup = layer->GetGroup();
-            if ((layer->IsVisible()) && (layerGroup.p == mggroup.p))
-            {
-                hasVisibleLayers = true;
-                break;
-            }
-        }
-        if (!hasVisibleLayers)
+        Ptr<MgLayerGroup> parentGroup = layer->GetGroup();
+        if (NULL == parentGroup.p) //No parent
             continue;
 
-        if (mggroup == NULL)
-        {
-            throw new MgNullReferenceException(L"MgdLegendPlotUtil.AddLegendElement", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-        Ptr<MgLayerGroup> mgparent = mggroup->GetGroup();
+        STRING parentGroupName = parentGroup->GetName();
+        VisibleLayerCountMap::iterator vit = visibleLayers.find(parentGroupName);
+        if (vit == visibleLayers.end())
+            visibleLayers[parentGroupName] = 0;
+        visibleLayers[parentGroupName]++;
+    }
 
-        double indent = 0;
-        while (mgparent)
+    for (INT32 i = 0; i < groups->GetCount(); i++)
+    {
+        Ptr<MgLayerGroup> group = groups->GetItem(i);
+        Ptr<MgLayerGroup> parentGroup = group->GetGroup();
+        if (NULL != parentGroup.p)
         {
-            indent += PrintGroupIndent;
-            mgparent = mgparent->GetGroup();
+            STRING groupName = group->GetName();
+            STRING parentGroupName = parentGroup->GetName();
+            LayerGroupChildMap::iterator cit = groupChildren.find(parentGroupName);
+            if (cit == groupChildren.end())
+                groupChildren[parentGroupName] = LayerGroupList();
+            groupChildren[parentGroupName].push_back(groupName);
         }
-
-        x = legendOffsetX + (defaultLegendMargin + indent)*convertUnits;
-
-        RS_LabelInfo info(x, y + legendTextVertAdjust*convertUnits, textDef);
-        dr.ProcessLabelGroup(&info, 1, mggroup->GetLegendLabel(), RS_OverpostType_All, false, NULL, 0.0);
-
-        y -= legendSpacing*convertUnits;
-
-        if (y < legendSpec->GetMarginBottom())
-            break;
-
-        // Process the layers
-        ProcessLayersForLegend(map, scale, mggroup, x, y, textDef, dr, legendSpec, legendOffsetY, convertUnits);
     }
 }
 
-
-void MgdLegendPlotUtil::ProcessLayersForLegend(MgdMap* map, double mapScale, MgLayerGroup* mggroup, double startX, double& startY, RS_TextDef textDef, Renderer& dr, MgdPlotSpecification* legendSpec, double legendOffsetY, double convertUnits)
+void MgdLegendPlotUtil::ProcessLayersForLegend(MgdMap* map, double mapScale, MgLayerGroup* mggroup, double startX, double& startY, RS_TextDef textDef, Renderer& dr, MgdPlotSpecification* legendSpec, double legendOffsetY, double convertUnits, VisibleLayerCountMap& visibleLayers, LayerGroupChildMap& groupChildren)
 {
     double x;
     double &y = startY;
@@ -268,24 +263,70 @@
             if (ftscol->GetCount() == 0)
                 continue;
 
-            // if there are multiple feature type styles, using the first one
-            MdfModel::FeatureTypeStyle* fts = ftscol->GetAt(0);
-            MdfModel::RuleCollection* rules = fts->GetRules();
-            int nRuleCount = rules->GetCount();
+            //Peek ahead to determine what we're dealing with
+            bool bThemed = false;
+            int nCompositeStyleCount = 0;
+            MdfModel::FeatureTypeStyle* singleFTS = NULL;
+            MdfModel::FeatureTypeStyle* singleCTS = NULL;
+            int nTotalFTSRules = 0;
+            int nTotalCTSRules = 0;
+            //Compile type/rule count to determine if this is a themed layer
+            for (int j = 0; j < ftscol->GetCount(); j++)
+            {
+                MdfModel::FeatureTypeStyle* fts = ftscol->GetAt(j);
+                if (!fts->IsShowInLegend())
+                    continue;
 
+                MdfModel::RuleCollection* rules = fts->GetRules();
+                MdfModel::CompositeTypeStyle* cts = dynamic_cast<MdfModel::CompositeTypeStyle*>(fts);
+                //Composite Styles take precedence (it's what the stylizer does. So we're doing the same thing here). 
+                //If a Composite Style exists, we're using it.
+                if (NULL != cts)
+                {
+                    //For a single type scale range, this will only be set once. Otherwise it could
+                    //be set many times over (for each style type we encounter), but this is okay 
+                    //because we won't be using this pointer anyway for multi-type layers
+                    singleCTS = fts;
+                    nTotalCTSRules += rules->GetCount();
+                    nCompositeStyleCount++;
+                }
+                else
+                {
+                    //For a single type scale range, this will only be set once. Otherwise it could
+                    //be set many times over (for each style type we encounter), but this is okay 
+                    //because we won't be using this pointer anyway for multi-type layers
+                    singleFTS = fts;
+                    nTotalFTSRules += rules->GetCount();
+                }
+            }
+            //It's a themed layer if we found more than one rule of that type
+            bThemed = (nTotalFTSRules > 1);
+            //Found a composite style, re-evaluate against composite rule count
+            if (nCompositeStyleCount > 0)
+                bThemed = (nTotalCTSRules > 1);
+
             //add the layer icon, if any
             x = startX;
             RS_Bounds b2(x, y, x + dIconWidth, y + dIconHeight);
 
-            if (nRuleCount > 1)
+            if (bThemed)
             {
                 //in case of themed layer, use standard theme icon
                 DrawPNG(&dr, (unsigned char*)THEMED_LAYER_ICON, sizeof(THEMED_LAYER_ICON), bitmapPixelWidth, bitmapPixelHeight, b2);
             }
             else
             {
+                assert(NULL != singleFTS || NULL != singleCTS); //Should've been set by peek-ahead from above
+
+                MdfModel::FeatureTypeStyle* theFTS = NULL;
+                //Composite TS takes precedence
+                if (NULL != singleCTS)
+                    theFTS = singleCTS;
+                else if (NULL != singleFTS)
+                    theFTS = singleFTS;
+
                 //otherwise pick the icon from the only rule
-                Ptr<MgByteReader> layerIcon = MgdMappingUtil::DrawFTS(m_svcResource, fts, bitmapPixelWidth, bitmapPixelHeight, 0);
+                Ptr<MgByteReader> layerIcon = MgdMappingUtil::DrawFTS(m_svcResource, theFTS, bitmapPixelWidth, bitmapPixelHeight, 0);
 
                 if (layerIcon.p)
                 {
@@ -303,38 +344,56 @@
             RS_LabelInfo info(x, y + verticalTextAdjust, textDef);
             dr.ProcessLabelGroup(&info, 1, mapLayer->GetLegendLabel(), RS_OverpostType_All, false, NULL, 0.0);
 
-            if (nRuleCount > 1)
+            //layer is themed : draw the theme icons under the layer title
+            if (bThemed)
             {
                 //theme icons draw slightly indented
                 x = startX + initialMarginX;
 
-                //layer is themed : draw the theme icons under the layer title
-                for (int i = 0; i < nRuleCount; i++)
+                for (int j = 0; j < ftscol->GetCount(); j++)
                 {
-                    MdfModel::Rule* rule = rules->GetAt(i);
+                    MdfModel::FeatureTypeStyle* fts = ftscol->GetAt(j);
+                    //Skip items not marked for display
+                    if (!fts->IsShowInLegend())
+                        continue;
 
-                    //move y cursor down one line
-                    y -= verticalDelta;
+                    MdfModel::CompositeTypeStyle* cts = dynamic_cast<MdfModel::CompositeTypeStyle*>(fts);
+                    //If we found one or more composite styles, then they take precedence. So skip all non-composite ones
+                    if (nCompositeStyleCount > 0 && NULL == cts)
+                        continue;
 
-                    if (y < bottomLimit)
-                        break;
+                    MdfModel::RuleCollection* rules = fts->GetRules();
 
-                    //draw the icon for the current theming rule
-                    Ptr<MgByteReader> rdr = MgdMappingUtil::DrawFTS(m_svcResource, fts, bitmapPixelWidth, bitmapPixelHeight, i);
-
-                    if (rdr != NULL)
+                    for (int k = 0; k < rules->GetCount(); k++)
                     {
-                        MgByteSink sink(rdr);
-                        Ptr<MgByte> bytes = sink.ToBuffer();
+                        MdfModel::Rule* rule = rules->GetAt(k);
 
-                        RS_Bounds b2(x, y, x + dIconWidth, y + dIconHeight);
-                        DrawPNG(&dr, bytes->Bytes(), bytes->GetLength(), bitmapPixelWidth, bitmapPixelHeight, b2);
+                        //move y cursor down one line
+                        y -= verticalDelta;
+
+                        if (y < bottomLimit)
+                            break;
+
+                        //draw the icon for the current theming rule
+                        Ptr<MgByteReader> rdr = MgdMappingUtil::DrawFTS(m_svcResource, fts, bitmapPixelWidth, bitmapPixelHeight, k);
+
+                        if (rdr != NULL)
+                        {
+                            MgByteSink sink(rdr);
+                            Ptr<MgByte> bytes = sink.ToBuffer();
+
+                            RS_Bounds b2(x, y, x + dIconWidth, y + dIconHeight);
+                            DrawPNG(&dr, bytes->Bytes(), bytes->GetLength(), bitmapPixelWidth, bitmapPixelHeight, b2);
+                        }
+
+                        //draw the label after the icon, but also allow
+                        //some blank space for better clarity
+                        RS_LabelInfo info(x + dIconWidth + initialMarginX, y + verticalTextAdjust, textDef);
+                        dr.ProcessLabelGroup(&info, 1, rule->GetLegendLabel(), RS_OverpostType_All, false, NULL, 0.0);
                     }
 
-                    //draw the label after the icon, but also allow
-                    //some blank space for better clarity
-                    RS_LabelInfo info(x + dIconWidth + initialMarginX, y + verticalTextAdjust, textDef);
-                    dr.ProcessLabelGroup(&info, 1, rule->GetLegendLabel(), RS_OverpostType_All, false, NULL, 0.0);
+                    if (y < bottomLimit)
+                        break;
                 }
             }
         }
@@ -1280,6 +1339,28 @@
     dr.EndLayout();
 }
 
+bool MgdLegendPlotUtil::HasVisibleLayers(CREFSTRING groupName, VisibleLayerCountMap& visibleLayers, LayerGroupChildMap& groupChildren)
+{
+    INT32 total = 0;
+    VisibleLayerCountMap::iterator vit = visibleLayers.find(groupName);
+    if (vit != visibleLayers.end())
+    {
+        if (vit->second > 0)
+            return true;
+    }
+
+    LayerGroupChildMap::iterator cit = groupChildren.find(groupName);
+    if (cit != groupChildren.end())
+    {
+        for (LayerGroupList::iterator lit = cit->second.begin(); lit != cit->second.end(); lit++)
+        {
+            if (HasVisibleLayers(*lit, visibleLayers, groupChildren))
+                return true;
+        }
+    }
+    return false;
+}
+
 //
 //  Compute the legend size and the offset position on the page
 //

Modified: trunk/MgDev/Desktop/MgDesktop/Services/Rendering/LegendPlotUtil.h
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Rendering/LegendPlotUtil.h	2013-11-27 11:55:44 UTC (rev 7934)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Rendering/LegendPlotUtil.h	2013-11-27 12:35:03 UTC (rev 7935)
@@ -3,6 +3,10 @@
 
 class EPlotRenderer;
 
+typedef std::vector<STRING> LayerGroupList;
+typedef std::map<STRING, LayerGroupList> LayerGroupChildMap;
+typedef std::map<STRING, int> VisibleLayerCountMap;
+
 class MG_DESKTOP_API MgdLegendPlotUtil
 {
 public:
@@ -25,12 +29,14 @@
     //Eventually the scale bar and north arrow ones need to be cleaned up also in order
     //to use them in the AJAX viewer
     void AddLegendElement(double dMapScale, Renderer& dr, MgdMap* map, MgdPlotSpecification* plotSpec, double legendOffsetX, double legendOffsetY);
-    void ProcessLayersForLegend(MgdMap* map, double mapScale, MgLayerGroup* mggroup, double startX, double& startY, RS_TextDef textDef, Renderer& dr, MgdPlotSpecification* plotSpec, double legendOffsetY, double convertUnits);
+    void ProcessLayersForLegend(MgdMap* map, double mapScale, MgLayerGroup* mggroup, double startX, double& startY, RS_TextDef textDef, Renderer& dr, MgdPlotSpecification* plotSpec, double legendOffsetY, double convertUnits, VisibleLayerCountMap& visibleLayers, LayerGroupChildMap& groupChildren);
     void BuildLegendContent(MgdMap* map, double scale, MgdPlotSpecification* legendSpec, double legendOffsetX, double legendOffsetY, Renderer& dr, double convertUnits);
 
     void ExtentFromMapCenter(MgdMap* map, double metersPerUnit, RS_Bounds& b);
+    void CompileInformation(MgdMap* map, VisibleLayerCountMap& visibleLayers, LayerGroupChildMap& groupChildren);
 
 private:
+    static bool HasVisibleLayers(CREFSTRING groupName, VisibleLayerCountMap& visibleLayers, LayerGroupChildMap& groupChildren);
 
     MgResourceService* m_svcResource;
     RS_String m_legendFontName;

Modified: trunk/MgDev/Desktop/UnitTest/TestRenderingService.cpp
===================================================================
--- trunk/MgDev/Desktop/UnitTest/TestRenderingService.cpp	2013-11-27 11:55:44 UTC (rev 7934)
+++ trunk/MgDev/Desktop/UnitTest/TestRenderingService.cpp	2013-11-27 12:35:03 UTC (rev 7935)
@@ -321,12 +321,45 @@
         Ptr<MgByteReader> dataReader7 = dataSource7->GetReader();
         m_svcResource->SetResourceData(fsres7, L"UT_VotingDistricts.sdf", L"File", dataReader7);
 
-        // Data related to stylization function tests
-        Ptr<MgResourceIdentifier> ldfres14 = new MgResourceIdentifier(L"Library://UnitTests/Layers/StylizationFuncs.LayerDefinition");
-        Ptr<MgByteSource> ldfsrc14 = new MgByteSource(L"../UnitTestFiles/UT_VotingDistrictsFunctions.ldf", false);
+        // ---------------------------------------------------------
+        // Data for exercising legend rendering
+        // ---------------------------------------------------------
+        Ptr<MgResourceIdentifier> ldfres14 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTS.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc14 = new MgByteSource(L"../UnitTestFiles/UT_MultiFTS.ldf", false);
         Ptr<MgByteReader> ldfrdr14 = ldfsrc14->GetReader();
         m_svcResource->SetResource(ldfres14, ldfrdr14, NULL);
 
+        Ptr<MgResourceIdentifier> ldfres15 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc15 = new MgByteSource(L"../UnitTestFiles/UT_MultiCTS.ldf", false);
+        Ptr<MgByteReader> ldfrdr15 = ldfsrc15->GetReader();
+        m_svcResource->SetResource(ldfres15, ldfrdr15, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres16 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTSWithTheme.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc16 = new MgByteSource(L"../UnitTestFiles/UT_MultiFTSWithTheme.ldf", false);
+        Ptr<MgByteReader> ldfrdr16 = ldfsrc16->GetReader();
+        m_svcResource->SetResource(ldfres16, ldfrdr16, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres17 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc17 = new MgByteSource(L"../UnitTestFiles/UT_MultiCTSWithTheme.ldf", false);
+        Ptr<MgByteReader> ldfrdr17 = ldfsrc17->GetReader();
+        m_svcResource->SetResource(ldfres17, ldfrdr17, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres18 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTSSingleCTS.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc18 = new MgByteSource(L"../UnitTestFiles/UT_MultiFTSSingleCTS.ldf", false);
+        Ptr<MgByteReader> ldfrdr18 = ldfsrc18->GetReader();
+        m_svcResource->SetResource(ldfres18, ldfrdr18, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres19 = new MgResourceIdentifier(L"Library://UnitTests/Layers/SingleFTSMultiCTS.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc19 = new MgByteSource(L"../UnitTestFiles/UT_SingleFTSMultiCTS.ldf", false);
+        Ptr<MgByteReader> ldfrdr19 = ldfsrc19->GetReader();
+        m_svcResource->SetResource(ldfres19, ldfrdr19, NULL);
+
+        // Data related to stylization function tests
+        Ptr<MgResourceIdentifier> ldfres20 = new MgResourceIdentifier(L"Library://UnitTests/Layers/StylizationFuncs.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc20 = new MgByteSource(L"../UnitTestFiles/UT_VotingDistrictsFunctions.ldf", false);
+        Ptr<MgByteReader> ldfrdr20 = ldfsrc20->GetReader();
+        m_svcResource->SetResource(ldfres20, ldfrdr20, NULL);
+
         Ptr<MgResourceIdentifier> mapres15 = new MgResourceIdentifier(L"Library://UnitTests/Maps/StylizationFuncs.MapDefinition");
         Ptr<MgByteSource> mdfsrc15 = new MgByteSource(L"../UnitTestFiles/UT_StylizationFuncs.mdf", false);
         Ptr<MgByteReader> mdfrdr15 = mdfsrc15->GetReader();
@@ -452,10 +485,23 @@
         Ptr<MgResourceIdentifier> fsres7 = new MgResourceIdentifier(L"Library://UnitTests/Data/VotingDistricts.FeatureSource");
         m_svcResource->DeleteResource(fsres7);
 
-        // Data related to stylization function tests
-        Ptr<MgResourceIdentifier> ldfres14 = new MgResourceIdentifier(L"Library://UnitTests/Layers/StylizationFuncs.LayerDefinition");
+        Ptr<MgResourceIdentifier> ldfres14 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTS.LayerDefinition");
         m_svcResource->DeleteResource(ldfres14);
+        Ptr<MgResourceIdentifier> ldfres15 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres15);
+        Ptr<MgResourceIdentifier> ldfres16 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTSWithTheme.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres16);
+        Ptr<MgResourceIdentifier> ldfres17 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres17);
+        Ptr<MgResourceIdentifier> ldfres18 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTSSingleCTS.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres18);
+        Ptr<MgResourceIdentifier> ldfres19 = new MgResourceIdentifier(L"Library://UnitTests/Layers/SingleFTSMultiCTS.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres19);
 
+        // Data related to stylization function tests
+        Ptr<MgResourceIdentifier> ldfres20 = new MgResourceIdentifier(L"Library://UnitTests/Layers/StylizationFuncs.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres20);
+
         Ptr<MgResourceIdentifier> mapres15 = new MgResourceIdentifier(L"Library://UnitTests/Maps/StylizationFuncs.MapDefinition");
         m_svcResource->DeleteResource(mapres15);
     }
@@ -687,6 +733,58 @@
     }
 }
 
+void TestRenderingService::TestCase_RenderLegendEmptyGroups(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgdMap> map = CreateTestMap();
+        map->SetViewScale(75000.0);
+        Ptr<MgColor> bgc = new MgColor(255, 255, 255, 255);
+
+        // Set up the following structure
+        //
+        // EmptyGroup1
+        // EmptyGroup2
+        //    EmptyGroup3
+        //
+        // None of these should be visible when we render the legend
+
+        Ptr<MgLayerGroupCollection> groups = map->GetLayerGroups();
+        Ptr<MgLayerGroup> group1 = new MgLayerGroup(L"EmptyGroup1");
+        group1->SetLegendLabel(L"EmptyGroup1");
+        Ptr<MgLayerGroup> group2 = new MgLayerGroup(L"EmptyGroup2");
+        group2->SetLegendLabel(L"EmptyGroup2");
+        Ptr<MgLayerGroup> group3 = new MgLayerGroup(L"EmptyGroup3");
+        group3->SetLegendLabel(L"EmptyGroup3");
+
+        group1->SetDisplayInLegend(true);
+        group2->SetDisplayInLegend(true);
+        group3->SetDisplayInLegend(true);
+
+        groups->Add(group1);
+        groups->Add(group2);
+        groups->Add(group3);
+        group3->SetGroup(group2);
+
+        map->Save();
+
+        // Call the API
+        Ptr<MgByteReader> rdr3 = m_svcRendering->RenderMapLegend(map, 200, 400, bgc, imageFormat);
+        rdr3->ToFile(GetPath(L"../UnitTestFiles/RenderLegendEmptyGroups", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
 void TestRenderingService::TestCase_StylizationFunctions(CREFSTRING imageFormat, CREFSTRING extension)
 {
     try
@@ -723,6 +821,211 @@
     }
 }
 
+void TestRenderingService::TestCase_RenderLegendMultiFTS(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgdMap> map = CreateTestMap();
+
+        // Insert our test layer
+        Ptr<MgResourceIdentifier> layerDef = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTS.LayerDefinition");
+        Ptr<MgdLayer> layer = new MgdLayer(layerDef, m_svcResource);
+        layer->SetLegendLabel(layerDef->GetName());
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+        map->Save();
+
+        // call the API using scales of 75000 and 12000
+        Ptr<MgColor> bgc = new MgColor(255, 255, 255, 255);
+
+        map->SetViewScale(75000.0);
+        Ptr<MgByteReader> rdr1 = m_svcRendering->RenderMapLegend(map, 200, 400, bgc, imageFormat);
+        rdr1->ToFile(GetPath(L"../UnitTestFiles/RenderLegendMultiFTS", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestRenderingService::TestCase_RenderLegendMultiCTS(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgdMap> map = CreateTestMap();
+
+        // Insert our test layer
+        Ptr<MgResourceIdentifier> layerDef = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition");
+        Ptr<MgdLayer> layer = new MgdLayer(layerDef, m_svcResource);
+        layer->SetLegendLabel(layerDef->GetName());
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+        map->Save();
+
+        // call the API using scales of 75000 and 12000
+        Ptr<MgColor> bgc = new MgColor(255, 255, 255, 255);
+
+        map->SetViewScale(75000.0);
+        Ptr<MgByteReader> rdr1 = m_svcRendering->RenderMapLegend(map, 200, 400, bgc, imageFormat);
+        rdr1->ToFile(GetPath(L"../UnitTestFiles/RenderLegendMultiCTS", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestRenderingService::TestCase_RenderLegendMultiFTSWithTheme(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgdMap> map = CreateTestMap();
+
+        // Insert our test layer
+        Ptr<MgResourceIdentifier> layerDef = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTSWithTheme.LayerDefinition");
+        Ptr<MgdLayer> layer = new MgdLayer(layerDef, m_svcResource);
+        layer->SetLegendLabel(layerDef->GetName());
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+        map->Save();
+
+        // call the API using scales of 75000 and 12000
+        Ptr<MgColor> bgc = new MgColor(255, 255, 255, 255);
+
+        map->SetViewScale(75000.0);
+        Ptr<MgByteReader> rdr1 = m_svcRendering->RenderMapLegend(map, 200, 400, bgc, imageFormat);
+        rdr1->ToFile(GetPath(L"../UnitTestFiles/RenderLegendMultiFTSWithTheme", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestRenderingService::TestCase_RenderLegendMultiCTSWithTheme(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgdMap> map = CreateTestMap();
+
+        // Insert our test layer
+        Ptr<MgResourceIdentifier> layerDef = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
+        Ptr<MgdLayer> layer = new MgdLayer(layerDef, m_svcResource);
+        layer->SetLegendLabel(layerDef->GetName());
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+        map->Save();
+
+        // call the API using scales of 75000 and 12000
+        Ptr<MgColor> bgc = new MgColor(255, 255, 255, 255);
+
+        map->SetViewScale(75000.0);
+        Ptr<MgByteReader> rdr1 = m_svcRendering->RenderMapLegend(map, 200, 400, bgc, imageFormat);
+        rdr1->ToFile(GetPath(L"../UnitTestFiles/RenderLegendMultiCTSWithTheme", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestRenderingService::TestCase_RenderLegendMultiFTSSingleCTS(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgdMap> map = CreateTestMap();
+
+        // Insert our test layer
+        Ptr<MgResourceIdentifier> layerDef = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiFTSSingleCTS.LayerDefinition");
+        Ptr<MgdLayer> layer = new MgdLayer(layerDef, m_svcResource);
+        layer->SetLegendLabel(layerDef->GetName());
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+        map->Save();
+
+        // call the API using scales of 75000 and 12000
+        Ptr<MgColor> bgc = new MgColor(255, 255, 255, 255);
+
+        map->SetViewScale(75000.0);
+        Ptr<MgByteReader> rdr1 = m_svcRendering->RenderMapLegend(map, 200, 400, bgc, imageFormat);
+        rdr1->ToFile(GetPath(L"../UnitTestFiles/RenderLegendMultiFTSSingleCTS", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+
+void TestRenderingService::TestCase_RenderLegendSingleFTSMultiCTS(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgdMap> map = CreateTestMap();
+
+        // Insert our test layer
+        Ptr<MgResourceIdentifier> layerDef = new MgResourceIdentifier(L"Library://UnitTests/Layers/SingleFTSMultiCTS.LayerDefinition");
+        Ptr<MgdLayer> layer = new MgdLayer(layerDef, m_svcResource);
+        layer->SetLegendLabel(layerDef->GetName());
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+        map->Save();
+
+        // call the API using scales of 75000 and 12000
+        Ptr<MgColor> bgc = new MgColor(255, 255, 255, 255);
+
+        map->SetViewScale(75000.0);
+        Ptr<MgByteReader> rdr1 = m_svcRendering->RenderMapLegend(map, 200, 400, bgc, imageFormat);
+        rdr1->ToFile(GetPath(L"../UnitTestFiles/RenderLegendSingleFTSMultiCTS", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
 void TestRenderingService::TestCase_QueryFeatures()
 {
     try

Modified: trunk/MgDev/Desktop/UnitTest/TestRenderingService.h
===================================================================
--- trunk/MgDev/Desktop/UnitTest/TestRenderingService.h	2013-11-27 11:55:44 UTC (rev 7934)
+++ trunk/MgDev/Desktop/UnitTest/TestRenderingService.h	2013-11-27 12:35:03 UTC (rev 7935)
@@ -42,6 +42,13 @@
     CPPUNIT_TEST(TestCase_RenderMapPNG);
     CPPUNIT_TEST(TestCase_RenderMapWithWatermarkPNG);
     CPPUNIT_TEST(TestCase_RenderLegendPNG);
+    CPPUNIT_TEST(TestCase_RenderLegendEmptyGroupsPNG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSPNG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiCTSPNG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSWithThemePNG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiCTSWithThemePNG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSSingleCTSPNG);
+    CPPUNIT_TEST(TestCase_RenderLegendSingleFTSMultiCTSPNG);
 
     CPPUNIT_TEST(TestCase_StylizationFunctionsPNG8);
 
@@ -60,6 +67,13 @@
     CPPUNIT_TEST(TestCase_RenderMapPNG8);
     CPPUNIT_TEST(TestCase_RenderMapWithWatermarkPNG8);
     CPPUNIT_TEST(TestCase_RenderLegendPNG8);
+    CPPUNIT_TEST(TestCase_RenderLegendEmptyGroupsPNG8);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSPNG8);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiCTSPNG8);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSWithThemePNG8);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiCTSWithThemePNG8);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSSingleCTSPNG8);
+    CPPUNIT_TEST(TestCase_RenderLegendSingleFTSMultiCTSPNG8);
 
     CPPUNIT_TEST(TestCase_StylizationFunctionsGIF);
 
@@ -78,6 +92,13 @@
     CPPUNIT_TEST(TestCase_RenderMapGIF);
     CPPUNIT_TEST(TestCase_RenderMapWithWatermarkGIF);
     CPPUNIT_TEST(TestCase_RenderLegendGIF);
+    CPPUNIT_TEST(TestCase_RenderLegendEmptyGroupsGIF);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSGIF);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiCTSGIF);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSWithThemeGIF);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiCTSWithThemeGIF);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSSingleCTSGIF);
+    CPPUNIT_TEST(TestCase_RenderLegendSingleFTSMultiCTSGIF);
 
     CPPUNIT_TEST(TestCase_StylizationFunctionsJPG);
 
@@ -96,6 +117,13 @@
     CPPUNIT_TEST(TestCase_RenderMapJPG);
     CPPUNIT_TEST(TestCase_RenderMapWithWatermarkJPG);
     CPPUNIT_TEST(TestCase_RenderLegendJPG);
+    CPPUNIT_TEST(TestCase_RenderLegendEmptyGroupsJPG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSJPG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiCTSJPG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSWithThemeJPG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiCTSWithThemeJPG);
+    CPPUNIT_TEST(TestCase_RenderLegendMultiFTSSingleCTSJPG);
+    CPPUNIT_TEST(TestCase_RenderLegendSingleFTSMultiCTSJPG);
 
     CPPUNIT_TEST(TestCase_QueryFeatures);
 
@@ -113,12 +141,21 @@
     void TestStart();
     void TestEnd();
 
+    void TestCase_QueryFeatures();
+
     //Parameterized versions that all format-specific tests call into
     void TestCase_RenderDynamicOverlay(CREFSTRING imageFormat, CREFSTRING extension);
     void TestCase_RenderDynamicOverlayTiledMap(CREFSTRING imageFormat, CREFSTRING extension);
     void TestCase_RenderMap(CREFSTRING imageFormat, CREFSTRING extension);
     void TestCase_RenderMapWithWatermark(CREFSTRING imageFormat, CREFSTRING extension);
     void TestCase_RenderLegend(CREFSTRING imageFormat, CREFSTRING extension);
+    void TestCase_RenderLegendEmptyGroups(CREFSTRING imageFormat, CREFSTRING extension);
+    void TestCase_RenderLegendMultiFTS(CREFSTRING imageFormat, CREFSTRING extension);
+    void TestCase_RenderLegendMultiCTS(CREFSTRING imageFormat, CREFSTRING extension);
+    void TestCase_RenderLegendMultiFTSWithTheme(CREFSTRING imageFormat, CREFSTRING extension);
+    void TestCase_RenderLegendMultiCTSWithTheme(CREFSTRING imageFormat, CREFSTRING extension);
+    void TestCase_RenderLegendMultiFTSSingleCTS(CREFSTRING imageFormat, CREFSTRING extension);
+    void TestCase_RenderLegendSingleFTSMultiCTS(CREFSTRING imageFormat, CREFSTRING extension);
     
     void TestCase_SymbologyPoints(CREFSTRING imageFormat, CREFSTRING extension);
     void TestCase_SymbologyPointsParam(CREFSTRING imageFormat, CREFSTRING extension);
@@ -132,12 +169,13 @@
 
     void TestCase_StylizationFunctions(CREFSTRING imageFormat, CREFSTRING extension);
 
-	//PNG output tests
-	void TestCase_RenderDynamicOverlayPNG() { TestCase_RenderDynamicOverlay(L"PNG", L"png"); }
+    //PNG output tests
+    void TestCase_RenderDynamicOverlayPNG() { TestCase_RenderDynamicOverlay(L"PNG", L"png"); }
     void TestCase_RenderDynamicOverlayTiledMapPNG() { TestCase_RenderDynamicOverlayTiledMap(L"PNG", L"png"); }
     void TestCase_RenderMapPNG() { TestCase_RenderMap(L"PNG", L"png"); }
     void TestCase_RenderMapWithWatermarkPNG() { TestCase_RenderMapWithWatermark(L"PNG", L"png"); }
     void TestCase_RenderLegendPNG() { TestCase_RenderLegend(L"PNG", L"png"); }
+    void TestCase_RenderLegendEmptyGroupsPNG() { TestCase_RenderLegendEmptyGroups(L"PNG", L"png"); }
     void TestCase_SymbologyPointsPNG() { TestCase_SymbologyPoints(L"PNG", L"png"); }
     void TestCase_SymbologyPointsParamPNG() { TestCase_SymbologyPointsParam(L"PNG", L"png"); }
     void TestCase_SymbologyLinesPNG() { TestCase_SymbologyLines(L"PNG", L"png"); }
@@ -146,14 +184,21 @@
     void TestCase_Annotation1PNG() { TestCase_Annotation1(L"PNG", L"png"); }
     void TestCase_Annotation2PNG() { TestCase_Annotation2(L"PNG", L"png"); }
     void TestCase_Annotation3PNG() { TestCase_Annotation3(L"PNG", L"png"); }
+    void TestCase_RenderLegendMultiFTSPNG() { TestCase_RenderLegendMultiFTS(L"PNG", L"png"); }
+    void TestCase_RenderLegendMultiCTSPNG() { TestCase_RenderLegendMultiCTS(L"PNG", L"png"); }
+    void TestCase_RenderLegendMultiFTSWithThemePNG() { TestCase_RenderLegendMultiFTSWithTheme(L"PNG", L"png"); }
+    void TestCase_RenderLegendMultiCTSWithThemePNG() { TestCase_RenderLegendMultiCTSWithTheme(L"PNG", L"png"); }
+    void TestCase_RenderLegendMultiFTSSingleCTSPNG() { TestCase_RenderLegendMultiFTSSingleCTS(L"PNG", L"png"); }
+    void TestCase_RenderLegendSingleFTSMultiCTSPNG() { TestCase_RenderLegendSingleFTSMultiCTS(L"PNG", L"png"); }
     void TestCase_StylizationFunctionsPNG() { TestCase_StylizationFunctions(L"PNG", L"png"); }
 
-	//PNG8 output tests
-	void TestCase_RenderDynamicOverlayPNG8() { TestCase_RenderDynamicOverlay(L"PNG8", L"png"); }
+    //PNG8 output tests
+    void TestCase_RenderDynamicOverlayPNG8() { TestCase_RenderDynamicOverlay(L"PNG8", L"png"); }
     void TestCase_RenderDynamicOverlayTiledMapPNG8() { TestCase_RenderDynamicOverlayTiledMap(L"PNG8", L"png"); }
     void TestCase_RenderMapPNG8() { TestCase_RenderMap(L"PNG8", L"png"); }
     void TestCase_RenderMapWithWatermarkPNG8() { TestCase_RenderMapWithWatermark(L"PNG8", L"png"); }
     void TestCase_RenderLegendPNG8() { TestCase_RenderLegend(L"PNG8", L"png"); }
+    void TestCase_RenderLegendEmptyGroupsPNG8() { TestCase_RenderLegendEmptyGroups(L"PNG8", L"png"); }
     void TestCase_SymbologyPointsPNG8() { TestCase_SymbologyPoints(L"PNG8", L"png"); }
     void TestCase_SymbologyPointsParamPNG8() { TestCase_SymbologyPointsParam(L"PNG8", L"png"); }
     void TestCase_SymbologyLinesPNG8() { TestCase_SymbologyLines(L"PNG8", L"png"); }
@@ -162,14 +207,21 @@
     void TestCase_Annotation1PNG8() { TestCase_Annotation1(L"PNG8", L"png"); }
     void TestCase_Annotation2PNG8() { TestCase_Annotation2(L"PNG8", L"png"); }
     void TestCase_Annotation3PNG8() { TestCase_Annotation3(L"PNG8", L"png"); }
+    void TestCase_RenderLegendMultiFTSPNG8() { TestCase_RenderLegendMultiFTS(L"PNG8", L"png"); }
+    void TestCase_RenderLegendMultiCTSPNG8() { TestCase_RenderLegendMultiCTS(L"PNG8", L"png"); }
+    void TestCase_RenderLegendMultiFTSWithThemePNG8() { TestCase_RenderLegendMultiFTSWithTheme(L"PNG8", L"png"); }
+    void TestCase_RenderLegendMultiCTSWithThemePNG8() { TestCase_RenderLegendMultiCTSWithTheme(L"PNG8", L"png"); }
+    void TestCase_RenderLegendMultiFTSSingleCTSPNG8() { TestCase_RenderLegendMultiFTSSingleCTS(L"PNG8", L"png"); }
+    void TestCase_RenderLegendSingleFTSMultiCTSPNG8() { TestCase_RenderLegendSingleFTSMultiCTS(L"PNG8", L"png"); }
     void TestCase_StylizationFunctionsPNG8() { TestCase_StylizationFunctions(L"PNG8", L"png"); }
 
-	//GIF output tests
-	void TestCase_RenderDynamicOverlayGIF() { TestCase_RenderDynamicOverlay(L"GIF", L"gif"); }
+    //GIF output tests
+    void TestCase_RenderDynamicOverlayGIF() { TestCase_RenderDynamicOverlay(L"GIF", L"gif"); }
     void TestCase_RenderDynamicOverlayTiledMapGIF() { TestCase_RenderDynamicOverlayTiledMap(L"GIF", L"gif"); }
     void TestCase_RenderMapGIF() { TestCase_RenderMap(L"GIF", L"gif"); }
     void TestCase_RenderMapWithWatermarkGIF() { TestCase_RenderMapWithWatermark(L"GIF", L"gif"); }
     void TestCase_RenderLegendGIF() { TestCase_RenderLegend(L"GIF", L"gif"); }
+    void TestCase_RenderLegendEmptyGroupsGIF() { TestCase_RenderLegendEmptyGroups(L"GIF", L"gif"); }
     void TestCase_SymbologyPointsGIF() { TestCase_SymbologyPoints(L"GIF", L"gif"); }
     void TestCase_SymbologyPointsParamGIF() { TestCase_SymbologyPointsParam(L"GIF", L"gif"); }
     void TestCase_SymbologyLinesGIF() { TestCase_SymbologyLines(L"GIF", L"gif"); }
@@ -178,14 +230,21 @@
     void TestCase_Annotation1GIF() { TestCase_Annotation1(L"GIF", L"gif"); }
     void TestCase_Annotation2GIF() { TestCase_Annotation2(L"GIF", L"gif"); }
     void TestCase_Annotation3GIF() { TestCase_Annotation3(L"GIF", L"gif"); }
+    void TestCase_RenderLegendMultiFTSGIF() { TestCase_RenderLegendMultiFTS(L"GIF", L"gif"); }
+    void TestCase_RenderLegendMultiCTSGIF() { TestCase_RenderLegendMultiCTS(L"GIF", L"gif"); }
+    void TestCase_RenderLegendMultiFTSWithThemeGIF() { TestCase_RenderLegendMultiFTSWithTheme(L"GIF", L"gif"); }
+    void TestCase_RenderLegendMultiCTSWithThemeGIF() { TestCase_RenderLegendMultiCTSWithTheme(L"GIF", L"gif"); }
+    void TestCase_RenderLegendMultiFTSSingleCTSGIF() { TestCase_RenderLegendMultiFTSSingleCTS(L"GIF", L"gif"); }
+    void TestCase_RenderLegendSingleFTSMultiCTSGIF() { TestCase_RenderLegendSingleFTSMultiCTS(L"GIF", L"gif"); }
     void TestCase_StylizationFunctionsGIF() { TestCase_StylizationFunctions(L"GIF", L"gif"); }
 
-	//JPG output tests
-	void TestCase_RenderDynamicOverlayJPG() { TestCase_RenderDynamicOverlay(L"JPG", L"jpg"); }
+    //JPG output tests
+    void TestCase_RenderDynamicOverlayJPG() { TestCase_RenderDynamicOverlay(L"JPG", L"jpg"); }
     void TestCase_RenderDynamicOverlayTiledMapJPG() { TestCase_RenderDynamicOverlayTiledMap(L"JPG", L"jpg"); }
     void TestCase_RenderMapJPG() { TestCase_RenderMap(L"JPG", L"jpg"); }
     void TestCase_RenderMapWithWatermarkJPG() { TestCase_RenderMapWithWatermark(L"JPG", L"jpg"); }
     void TestCase_RenderLegendJPG() { TestCase_RenderLegend(L"JPG", L"jpg"); }
+    void TestCase_RenderLegendEmptyGroupsJPG() { TestCase_RenderLegendEmptyGroups(L"JPG", L"jpg"); }
     void TestCase_SymbologyPointsJPG() { TestCase_SymbologyPoints(L"JPG", L"jpg"); }
     void TestCase_SymbologyPointsParamJPG() { TestCase_SymbologyPointsParam(L"JPG", L"jpg"); }
     void TestCase_SymbologyLinesJPG() { TestCase_SymbologyLines(L"JPG", L"jpg"); }
@@ -194,10 +253,14 @@
     void TestCase_Annotation1JPG() { TestCase_Annotation1(L"JPG", L"jpg"); }
     void TestCase_Annotation2JPG() { TestCase_Annotation2(L"JPG", L"jpg"); }
     void TestCase_Annotation3JPG() { TestCase_Annotation3(L"JPG", L"jpg"); }
+    void TestCase_RenderLegendMultiFTSJPG() { TestCase_RenderLegendMultiFTS(L"JPG", L"jpg"); }
+    void TestCase_RenderLegendMultiCTSJPG() { TestCase_RenderLegendMultiCTS(L"JPG", L"jpg"); }
+    void TestCase_RenderLegendMultiFTSWithThemeJPG() { TestCase_RenderLegendMultiFTSWithTheme(L"JPG", L"jpg"); }
+    void TestCase_RenderLegendMultiCTSWithThemeJPG() { TestCase_RenderLegendMultiCTSWithTheme(L"JPG", L"jpg"); }
+    void TestCase_RenderLegendMultiFTSSingleCTSJPG() { TestCase_RenderLegendMultiFTSSingleCTS(L"JPG", L"jpg"); }
+    void TestCase_RenderLegendSingleFTSMultiCTSJPG() { TestCase_RenderLegendSingleFTSMultiCTS(L"JPG", L"jpg"); }
     void TestCase_StylizationFunctionsJPG() { TestCase_StylizationFunctions(L"JPG", L"jpg"); }
 
-    void TestCase_QueryFeatures();
-
     //void TestCase_RendererPerformance();
 
 private:



More information about the mapguide-commits mailing list